Let’s say I have an object who’s class definition looks like:
class Command:
foo = 5
def run(self, bar):
time.sleep(1)
self.foo = bar
return self.foo
If this class is instantiated once, but different threads are hitting its run method (via an HTTP request, handled separately) passing in different args, what is the best method to queue them? Can this be done in the class definition itself?
I am using an XML RPC server (separate class). For simplicity’s sake, we can say it has one instance of the Command class instantiated as a class variable. When Command.run() is being hit by two separate threads, how can I make sure that one run() method is complete before the next one is started?
I could do something like:
while self.busy:
time.sleep(1)
self.busy = true
...
self.busy = false
return self.foo
but that, as far as I know, would not give priority to the oldest request.
I realize how redundant this whole exercise sounds, since I could just run the XML-RPC server synchronously. But, to make a long story short, there are multiple Command instantiations and I do not want to block requests for one because another is busy.
I hope this makes more sense.
Thanks.
Here’s a relatively simple approach (ignores exceptions, attribute-access, special methods, etc):
With this “serializer”, you can do
and now all calls to myobj’s (non-special) methods are serialized in a thread-safe way.
For your specific case, where there’s only one method on the object, you could simplify this a bit further, but this is an already-simplified version of something I wrote and use often (supporting attribute getting and setting, special methods, etc, is a tad too complex to be worth it; the complete version does support catching and reraising exceptions raised in the wrapper object’s methods, an optimization for calls whose results or exceptions you don’t care about, and a few more tweaks, but not serialization of attributes and special methods).