GearmanBundle icon indicating copy to clipboard operation
GearmanBundle copied to clipboard

Define job callable name per Annotation

Open wildpascal opened this issue 8 years ago • 2 comments

Is it possible to define the callable name of a job per annotation?

We don´t want so long names for our queues especially we want to remove the "~" sign out of the name.

wildpascal avatar Dec 18 '15 13:12 wildpascal

Seconded. I would go even further, allow job configuration without annotations.

pinkeen avatar Nov 16 '16 12:11 pinkeen

I have been flummoxed by this behavior as well.

Fundamental Question:

Can the archetypal example, reverse, be replicated with this bundle?

Example Code (copied verbatim from the gearman.org home page):

// Reverse Client Code
$client = new GearmanClient();
$client->addServer();
print $client->do("reverse", "Hello World!");
// Reverse Worker Code
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction("reverse", function ($job) {
  return strrev($job->workload());
});
while ($worker->work());

Above, the Client notifies the Job Server that it wants the reverse Function to be performed. When the Worker boots it informs the Job Server that it has the ability to perform the reverse Function. Moreover, additional Workers may be spawned at anytime that are also able to perform reverse (and/or other abilities). The Client does not care, and should not care, which Worker performs reverse, it only cares that the Job Server knows that it wants reverse performed. The Job Server then coordinates what Worker to delegate the work of reverse to.

Takeaway:

Function names are global throughout the cluster. This makes sense because all components (Clients, Workers, Job Servers) must know what Function to associate a unit of work.

The bundle in its current state, as far as I can tell, is unable to replicate the reverse example.

⚠️The inability appears due to the fact that Worker's register their Functions to the Job Server in a manner that couples Worker and Function name via string concatenation that's stitched together via a (non-configurable) tilde (~) character:

Current Behavior:

WorkerA registers WorkerA~reverse, with Job Server. WorkerB registers WorkerB~reverse, with Job Server. WorkerC registers WorkerC~reverse, with Job Server.

Desired Behavior:

WorkerA registers reverse, with Job Server. WorkerB registers reverse, with Job Server. WorkerC registers reverse, with Job Server.

So, as indicated above, the current behavior is that even though we want and expect to be able to universally reference reverse within an entire cluster, the bundle instead registers N different (N = Number of Workers that CAN_DO reverse) Functions: "WorkerA~reverse", "WorkerB~reverse", ad infinitum, which from the Job Server's perspective are all different. The Client's perspective is untenable at best, and impossible at worst, because it's required to choose which name to use, when at the end of the day, it only wants to say: "Hey Job Server, do reverse, please!".

Client Must Choose:

// Do I ...
$gearman->doJob("WorkerA~reverse", "Hello World!");
// Or do I ...
$gearman->doJob("WorkerB~reverse", "Hello World!");
// Or do I ...
$gearman->doJob("WorkerC~reverse", "Hello World!");
// ...

Client Need Not Choose:

// I do exactly what I want!
$gearman->doJob("reverse", "Hello World!");

In previous attempts, the closest I could get was a ~reverse Function, but IIRC, the bundle required that each worker possess a unique name (in this case an empty string "", so ~reverse could only be used by one worker).

This is a gaping limitation to utilizing Gearman to its full potential, which in my eyes is as a "massively distributed operating system". Or as @joestump (creator of Net_Gearman, and who utilized Gearman at Digg, is oft quoted of thinking of Gearman as ...

"... a massively distributed, massively fault tolerant fork mechanism."

This seemingly subtle naming nuance can lead to extremely adverse effects within real-world Gearman clusters. The situation get amplified when incorporating more languages or even when using the gearman CLI.

Since the simplest scenario cannot be reproduced (the global reverse function), and all code predicates from that, I'm likening this to installing the roof of my house in an unbeknownst to me, flawed way, which could lead to leaks (headaches) in the future: If I lived in a dry environment I'm probably ok, but when it rains, sometimes there's some drip-drip, but I don't know why. If I lived in a wet climate I see the drip-drip more often and water starts seeping through my walls. If I were in the wettest of climates (Nepal in monsoon season watch out!!!), my entire house would be destroyed directly due to water damage, but indirectly due to the roof. Anyone who's ever worked on a house knows how a leaky roof can be devastatingly difficult problem to diagnose and fix and can lead to significant headache and damage! :sweat_smile:

If anyone knows a way around these points/issues please share. :beers:

Proposed Action Items:

  • [ ] Add configuration that "turns on" Worker/Function name coupling. Configuration should default to false to maintain BC.
  • [ ] Refactor code so that Workers register Function names exactly as defined by the user and Workers are correctly invoked to execute such Jobs when asked by the Job Server.
  • [ ] Tests:
    • [ ] Worker must register Function, reverse, with Job Server when the Worker is configured to process Job's named reverse. Note, this test should pass for any string allowed by the protocol, not just reverse.
    • [ ] Any Worker configured to process Job, reverse, when requested to do so by Job Server, must perform the operation successfully. Note, the Worker name configuration should be entirely irrelevant. Only the Function (Job name) matters.

/cc @pinkeen @wildpascal

bmeynell avatar Jan 28 '18 22:01 bmeynell