Can I register Gearman functions after starting the worker?

Asked by Khai Do

I have a use case where I want to register additional gearman functions and unregister functions after starting the worker. It doesn't seem like I can do this because the worker.work() method is a blocking call. Is there a workaround?

Question information

Language:
English Edit question
Status:
Answered
For:
Gearman Java Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Eric Lambert (elambert) said :
#1

Call the add/register/un-register from a second thread (but i cant recall if that is a thread safe path)?

But I am glad you bring that up because as part of the fix for https://bugs.launchpad.net/gearman-java/+bug/1098816 I was thinking of deprecating most of the mutating operations (register/unregister/set id, etc) methods on the Worker interface.The current implementation lets you create a new instance of worker via the constructor and then lets you configure it. What I was thinking of doing was using a Builder pattern instead to create the worker and that once you built the worker you would not be able to modify it (with the exception of starting and stoping it) This would make the Worker much easier to make thread safe and also simplify the implementation.

In pseudo code it might look something like this

WorkerBuilder b = new WorkerBuilder();
b.addServer("host", 4730);
b.registerFunctionFactory(someGearmanFunctionFactory);
GearmanWorker worker = b.build();
worker.work();

In this case if you wanted to add/remove a server or function you would need to create a new worker instance but the builder implementation would make that relatively easy by allowing you to clone an existing worker. Something like the following

WorkerBuilder b = WorkerBuilder.cloneWorker(worker);
b.addServer("host1",4730);
b.unregisterFunction(someFunction);
GearmanWorker workerPrime = b.build();
workerPrime.work();

What do you think?

Revision history for this message
James E. Blair (corvus) said :
#2

Personally, I find the mutating model attractive; the protocol allows a worker to dynamically change what functions it can run over time, and this lighter-weight approach to a changing system seems like a good use case to support. To use Khai's Jenkins integration project as an example: new jobs can be added and removed from Jenkins all the time. That's logically separate from when a worker registers or deregisters with Gearman (the logical analog in this case is a Jenkins slave or executor coming on or offline).

One solution would be to de-register and re-register workers when their functions change, but if a worker is capable of running multiple jobs simultaneously, then that solution won't work (deregistering a worker which is running a job to change its set of functions is not going to work).

I suppose it depends on exactly what your goals are with this level of the API; we can always use lower-level interfaces if you want the high-level ones to have stronger opinions on usage. But again, personally, I think it would be good and useful to support all of the aspects of the Gearman protocol even in the high-level Worker interface, including mutating function sets.

Revision history for this message
Eric Lambert (elambert) said :
#3

Hey, thanks for the feedback.

My goal here was to simplify the worker implementation (thereby make it more maintainable and less bug prone) as in my mind the set of functions that worker supports are relatively static --but your use case seems to state otherwise-- in which case this seemed like a reasonable trade-off to me.

Given your concerns, I'll keep things the way they are now (with the addition of the ability to grab job UUIDs, and maybe make the work() method non-blocking).

Revision history for this message
Khai Do (zaro0508) said :
#4

I am able to work around this issue by updating the gearman functions on a separate thread.

Revision history for this message
Khai Do (zaro0508) said :
#5

Updating gearman functions on a separate thread is not thread safe. It fails to register and unregister functions when the gearman worker (task) is in certain states. I get an IllegalStateException when attempting to update a gearman function when the worker task is in a FINISHED state.

Revision history for this message
Brian Aker (brianaker) said :
#6

In the protocol a worker can deregister a function any time it likes.

Can you help with this problem?

Provide an answer of your own, or ask Khai Do for more information if necessary.

To post a message you must log in.