how do i register function names with workers?

Asked by Khai Do on 2013-01-03

Hello. I have a question about how to register function names with workers. It isn't straight forward from the gearman-java examples how i can map an arbitrary name to gearman worker functions.

In the example the worker registers the ReverseFunction by getting the class and automatically setting the function name to 'org.gearman.example.ReverseFunction'.

How can I change that function name to just 'reverse'? or what if i want to register the same function with a different name like 'reverse_a_string'?

Question information

Language:
English Edit question
Status:
Solved
For:
Gearman Java Edit question
Assignee:
No assignee Edit question
Solved by:
Eric Lambert
Solved:
2013-01-05
Last query:
2013-01-05
Last reply:
2013-01-05
Eric Lambert (elambert) said : #1

Khai:

It is up to the Function's implementation to determine what name is used. The worker registers the function with the server using the result of the Function's getName() method. So, for example, if the implementation of a Function's getName() method returns the string "aFunction" then that function will be registered with the server using the name "aFunction".

If you are writing your own function you are free to implement getName to behave as you see fit (For example it can always return some constant value or it could provide some means of letting the user customize it's name).

If you are trying to change the name of some pre-existing function you can always extend it and override the getName() method.

Note, if your function extends AbstractGearmanFunction and you do not to override the getName() method, the default behavior is to use the class name as the name of the function.

Hope this helps.

Eric

Eric Lambert (elambert) said : #2

Also, forgot to mention that the constructor of AbstractGearmanFunction takes a string which sets the name.

Khai Do (zaro0508) said : #3

Thanks for the quick response . The getName() isn't what I want because I don't want the function name to be the same on every instance of the Function Class. I want to set a different function name everytime I register the function so that I can register multiple function names to the same class. like..

"org.gearman.example.ReverseFunction" - ReverseFunction
"reverse" - ReverseFunction
"revers_a_string" - ReverseFunction
etc..

I did create a constructor in ReverseFunction class that sets the name. However when worker attempted to register the function it fails with an 'java.lang.IllegalStateException'.

Here's the function:

public class ReverseFunction extends AbstractGearmanFunction {

 public ReverseFunction(String name) {
  super(name);
 }

 public GearmanJobResult executeFunction() {
          StringBuffer sb = new StringBuffer(ByteUtils.fromUTF8Bytes((byte[]) this.data));
          GearmanJobResult gjr = new GearmanJobResultImpl(this.jobHandle,
                true, sb.reverse().toString().getBytes(),
                new byte[0], new byte[0], 0, 0);
          return gjr;
       }
}

Here's the how I register the function..

GearmanWorker worker = new GearmanWorkerImpl();
worker.addServer(new GearmanNIOJobServerConnection(Constants.GEARMAN_DEFAULT_TCP_HOST, Constants.GEARMAN_DEFAULT_TCP_PORT));
ReverseFunction rf = new ReverseFunction("reverse");
worker.registerFunction(rf.getClass()); // fails with an java.lang.IllegalStateException

Best Eric Lambert (elambert) said : #4

OK, thanks for the clarification and the code snippet.

Yep, you are right, passing in the name in the constructor for AbstractGearmFunction does not work. Sorry for the bad info.

But you can accomplish what you are tying to do. Instead of registering a function with the worker, register a new instance of a function factory with the worker. The result of the getFunctionName() method on the factory will be used when registering the function with server. Fortunately the DefaultGearmanFunctionFactory has a constructor that takes a name as an argument which should make this easy for you to do.

For example, if you wanted to register the org.gearman.example.ReverseFunction with the names foo, bar,baz, boo you could do something like the following

 GearmanWorker worker = new GearmanWorkerImpl();
        worker.addServer(new GearmanNIOJobServerConnection("localhost",4730));
        worker.registerFunctionFactory(new DefaultGearmanFunctionFactory("foo", ReverseFunction.class.getName()));
        worker.registerFunctionFactory(new DefaultGearmanFunctionFactory("bar", ReverseFunction.class.getName()));
        worker.registerFunctionFactory(new DefaultGearmanFunctionFactory("baz", ReverseFunction.class.getName()));
        worker.registerFunctionFactory(new DefaultGearmanFunctionFactory("boo", ReverseFunction.class.getName()));
        worker.work();

as you can see from the calling status on the gearman server, we now have the appropriately named functions registered with the server

smacky:~ elambert$ telnet localhost 4730
Trying ::1...
Connected to localhost.
Escape character is '^]'.
status
boo 0 0 1
baz 0 0 1
bar 0 0 1
foo 0 0 1
.

Hope this helps.

Eric

Khai Do (zaro0508) said : #5

Thanks Eric Lambert, that solved my question.