Demonstrate how to create a multiprocessing's manager server exposing a class.
from multiprocessing.managers import BaseProxy
class GeneratorProxy(BaseProxy):
"""Manager's proxy for generators.
"""
_exposed_ = ["__next__"]
def __iter__(self):
return self
def __next__(self):
return self._callmethod("__next__")
from multiprocessing.managers import BaseManager, BaseProxy
from proxies import GeneratorProxy
class App:
"""Exposed class.
"""
def __init__(self, name: str):
self.name = name
def echo(self, data: str=''):
print(f"{self.name}: {data}")
def giveback(self, value):
return value
def split(self, data: str, by: str):
for token in data.split(by):
yield token
# Manager server class.
class Server(BaseManager): pass
# Registers the ``App`` class.
# The generator method ``App.split`` must be bound to the custom proxy ``GeneratorProxy``.
Server.register("App", App, method_to_typeid={"split": "App.split"})
Server.register("App.split", proxytype=GeneratorProxy)
# Creates and run a server instance.
server = Server(address=('', 50000), authkey=b"123")
server.get_server().serve_forever()
from multiprocessing.managers import BaseManager
from proxies import GeneratorProxy
# Manager
class Client(BaseManager): pass
# Registers the ``App`` class.
# The generator method ``App.split`` must be bound to the custom proxy ``GeneratorProxy``.
Client.register("App", method_to_typeid={"split": "App.split"})
Client.register("App.split", proxytype=GeneratorProxy)
# Connects to a remote server.
client = Client(address=('', 50000), authkey=b"123")
client.connect()
# Creates a new ``App`` instance remotely.
app = client.App(name="Client #1")
# Invokes the remotes ``App`` methods.
app.echo("Hello, World !")
print(app.giveback("Foobar"))
print(list(app.split(data="Hello,World !", by=",")))