I'm trying to make a class object usable for multiple processes. Unfortunarely this seems to be more of an issue than I anticipated.
I have the following class object:
class BusObject:
inputs: IOObject
outputs: IOObject
def __init__(self):
self.inputs = IOObject()
self.outputs = IOObject()
with the subclass IOObject
class IOObject:
idx: List[int] # signal index
tag: List[str] # signal tag
def __init__(self):
self.idx = []
self.tag = []
This combination worked fine. But now I run into the requirement that I have to make the BusObject available to multiple processes.
Therefore I created a custom multiprocessing.manager
class CustomManager(BaseManager):
pass
def main():
manager = CustomManager()
# Registration of custom classes to manager
manager.register('BusObject', BusObject)
# manager.register('IOObject', IOObject)
manager.start()
busObject = manager.BusObject()
Works - almost ...
The problem is that the subclass doesn't seem to be registered as well.
I tried to register the subclass, too, but even if I do I run into the error
AttributeError
'AutoProxy[BusObject]' object has no attribute 'inputs'
Any ideas?
CodePudding user response:
Since BusObject
contains IOObject
, try registering IOObject
first, then BusObject
.
CodePudding user response:
Upon reading the docs here - https://docs.python.org/3/library/multiprocessing.html#multiprocessing.managers.BaseManager.register - I 'd say you won't be able to access the .inputs
and .outputs
attributes directly - you can code your object like that, and the "owner" process of the real BusObject instance can do so - but in order to get instances for the IOObject
s that are associated to a BUSObject
(by the way, the term you are missing is this: associated objects, not "nested subclasses") - you have to retrieve then through methods that are registered in the method_to_typeid
parameter of the call to .register()
.
So, you'd do
...
def get_inputs(self):
return self.inputs
# same for outputs...
method (which otherwise looks silly in Python), and pass {'get_inputs': 'IOObject', 'get_outputs': 'IOObject'}
as the method_to_typeid
argument on the call to register.
That way, the other defaults of registering a class will create a proxy for BUSObject that will be able to return proxies to IOObject when you call these methods (but busobj_instance.inputs
should remain opaque).
It is even possible this can play along with @property
so you can register the property getter method as a proxy-returner and be able to use the names as attributes.
Of course, the IOOBject
class must be properly registered as well.
Sorry for not providing a working example and testing out the possibilities - but that would take me at least a couple hours to get going.