F
Frank Millman
Hi all
I am experimenting with the multiprocessing module, to get a feel of what is
possible and what is not. I have got a situation that does not behave as
expected. I can work around it, but I would like to find out the underlying
reason, to get a more solid understanding.
I am trying to create 'remote objects' that can be shared between processes.
I can create and return an instance of a class, with no problem. Now I want
to add a method to the class which, when called remotely, creates and
returns an instance of another class. I cannot get this to work.
On the server side I have -
tables = {} # a cache of table instances, keyed on name
class Table(object):
def __init__(self, name):
self.name = name
def get_table(self, tablename):
# if table with this name does not exist,
# create it and store it in cache
if tablename not in tables:
tables[tablename] = Table(tablename)
# retrieve table instance from cache and return it
return tables[tablename]
class MyManager(BaseManager): pass
MyManager.register('get_table', get_table,
method_to_typeid={'get_table': 'Table')
MyManager.register('Table', Table)
if __name__ == '__main__':
manager = MyManager(address=('127.0.0.1', 50000))
server = manager.get_server()
server.serve_forever()
On the client side I have -
class MyManager(BaseManager): pass
MyManager.register('get_table')
MyManager.register('Table')
if __name__ == '__main__':
manager = MyManager(address=('127.0.0.1', 50000))
manager.connect()
cust = manager.get_table('Customers')
So far so good.
Then I extend the server program as follows -
class Table(object):
def __init__(self, name):
self.name = name
+ self.columns = {}
+ def add_column(self, colname):
+ if colname not in self.columns:
+ self.columns[colname] = Column(colname)
+ return self.columns[colname]
+ class Column(object):
+ def __init__(self, colname):
+ self.colname = colname
MyManager.register('get_table', get_table,
method_to_typeid={'get_table': 'Table')
- MyManager.register('Table', Table)
+ MyManager.register('Table', Table,
+ method_to_typeid={'add_column': 'Column')
+ MyManager.register('Column', Column)
and I extend the client program as follows -
MyManager.register('get_table')
MyManager.register('Table')
+ MyManager.register('Column')
cust = manager.get_table('Customers')
+ acno = cust.add_column('Acno')
The server appears to create and return the column ok, but on the client
side I get the following traceback -
Traceback (most recent call last):
File "F:\junk\multiprocess\mp13b.py", line 29, in <module>
acno = cust.add_column('Acno')
File "<string>", line 2, in add_column
File "C:\Python26\lib\multiprocessing\managers.py", line 726, in
_callmethod
kind, result = conn.recv()
AttributeError: 'module' object has no attribute 'Column'
Does anyone know if it is possible to do what I am attempting, and what the
correct approach is?
BTW, version is Python 2.6.2.
Thanks
Frank Millman
I am experimenting with the multiprocessing module, to get a feel of what is
possible and what is not. I have got a situation that does not behave as
expected. I can work around it, but I would like to find out the underlying
reason, to get a more solid understanding.
I am trying to create 'remote objects' that can be shared between processes.
I can create and return an instance of a class, with no problem. Now I want
to add a method to the class which, when called remotely, creates and
returns an instance of another class. I cannot get this to work.
On the server side I have -
tables = {} # a cache of table instances, keyed on name
class Table(object):
def __init__(self, name):
self.name = name
def get_table(self, tablename):
# if table with this name does not exist,
# create it and store it in cache
if tablename not in tables:
tables[tablename] = Table(tablename)
# retrieve table instance from cache and return it
return tables[tablename]
class MyManager(BaseManager): pass
MyManager.register('get_table', get_table,
method_to_typeid={'get_table': 'Table')
MyManager.register('Table', Table)
if __name__ == '__main__':
manager = MyManager(address=('127.0.0.1', 50000))
server = manager.get_server()
server.serve_forever()
On the client side I have -
class MyManager(BaseManager): pass
MyManager.register('get_table')
MyManager.register('Table')
if __name__ == '__main__':
manager = MyManager(address=('127.0.0.1', 50000))
manager.connect()
cust = manager.get_table('Customers')
So far so good.
Then I extend the server program as follows -
class Table(object):
def __init__(self, name):
self.name = name
+ self.columns = {}
+ def add_column(self, colname):
+ if colname not in self.columns:
+ self.columns[colname] = Column(colname)
+ return self.columns[colname]
+ class Column(object):
+ def __init__(self, colname):
+ self.colname = colname
MyManager.register('get_table', get_table,
method_to_typeid={'get_table': 'Table')
- MyManager.register('Table', Table)
+ MyManager.register('Table', Table,
+ method_to_typeid={'add_column': 'Column')
+ MyManager.register('Column', Column)
and I extend the client program as follows -
MyManager.register('get_table')
MyManager.register('Table')
+ MyManager.register('Column')
cust = manager.get_table('Customers')
+ acno = cust.add_column('Acno')
The server appears to create and return the column ok, but on the client
side I get the following traceback -
Traceback (most recent call last):
File "F:\junk\multiprocess\mp13b.py", line 29, in <module>
acno = cust.add_column('Acno')
File "<string>", line 2, in add_column
File "C:\Python26\lib\multiprocessing\managers.py", line 726, in
_callmethod
kind, result = conn.recv()
AttributeError: 'module' object has no attribute 'Column'
Does anyone know if it is possible to do what I am attempting, and what the
correct approach is?
BTW, version is Python 2.6.2.
Thanks
Frank Millman