Можно ли сериализовать код тасклета (а не только состояние exec) с помощью SPickle без выполнения RPC? - PullRequest
0 голосов
/ 10 марта 2012

Попытка использовать Python без стека (2.7.2) с SPickle для отправки метода тестирования через сельдерей для выполнения на другой машине.Я хотел бы, чтобы тестовый метод (код) был включен в pickle и не был вынужден существовать на пути Python исполняющих машин.

Ссылка на следующую презентацию: https://ep2012.europython.eu/conference/talks/advanced-pickling-with-stackless-python-and-spickle

Попытка использованиятехника, показанная на слайде с контрольными точками 11. Пример RPC не выглядит правильным, учитывая, что мы используем сельдерей:

Код клиента:

from stackless import run, schedule, tasklet
from sPickle import SPickleTools


def test_method():
    print "hello from test method"

tasks = []
test_tasklet = tasklet(test_method)()
tasks.append(test_tasklet)

pt = SPickleTools(serializeableModules=['__test_method__'])
pickled_task = pt.dumps(tasks)

Код сервера:

pt = sPickle.SPickleTools()
unpickledTasks = pt.loads(pickled_task)

Результаты:

[2012-03-09 14:24:59,104: ERROR/MainProcess] Task    
celery_tasks.test_exec_method[8f462bd6-7952-4aa1-9adc-d84ee4a51ea6] raised exception:   
AttributeError("'module'
object has no attribute 'test_method'",)
Traceback (most recent call last):
File "c:\Python27\lib\site-packages\celery\execute\trace.py", line 153, in trace_task
R = retval = task(*args, **kwargs)
File "c:\Python27\celery_tasks.py", line 16, in test_exec_method
unpickledTasks = pt.loads(pickled_task)
File "c:\Python27\lib\site-packages\sPickle\_sPickle.py", line 946, in loads
return unpickler.load()
AttributeError: 'module' object has no attribute 'test_method'

Любые предложения о том, что я делаю неправильно, или если это вообще возможно?

Альтернативные предложения для выполнения динамической загрузки модуля в celeryd также будутхорошо (как альтернатива для использования sPickle).Я экспериментировал с выполнением:

py_mod = imp.load_source(module_name,'some script path')
sys.modules.setdefault(module_name,py_mod)

, но динамически загруженный модуль, похоже, не сохраняется при разных вызовах celeryd, т.е. при разных удаленных вызовах.

1 Ответ

1 голос
/ 24 июня 2012

Вы должны определить test_method в своем собственном модуле. В настоящее время sPickle определяет, определено ли test_method в модуле, который можно импортировать. Альтернативный способ - установить для атрибута __module__ функции значение None.

.
def test_method():
    pass

test_method.__module__ = None
...