Python 使用Pyro4和instance#u mode='创建非惰性实例;单个';

Python 使用Pyro4和instance#u mode='创建非惰性实例;单个';,python,daemon,pyro,Python,Daemon,Pyro,我的目标是为web框架提供对Pyro守护进程的访问,该守护进程在第一次加载时具有耗时的任务。到目前为止,我已经设法在内存中(在web应用程序之外)保留了一个类的单个实例,该实例负责在初始化时进行耗时的加载。我也可以用我的web应用程序查询它。守护进程的代码是: Pyro4.expose @Pyro4.behavior(instance_mode='single') class Store(object): def __init__(self): self._store

我的目标是为web框架提供对Pyro守护进程的访问,该守护进程在第一次加载时具有耗时的任务。到目前为止,我已经设法在内存中(在web应用程序之外)保留了一个类的单个实例,该实例负责在初始化时进行耗时的加载。我也可以用我的web应用程序查询它。守护进程的代码是:

Pyro4.expose
@Pyro4.behavior(instance_mode='single')
class Store(object):

    def __init__(self):
        self._store = ... # the expensive loading

    def query_store(self, query):
        return ... # Useful query tool to expose to the web framework.
                   # Not time consuming, provided self._store is
                   # loaded.

with Pyro4.Daemon() as daemon:
    uri = daemon.register(Thing)
    with Pyro4.locateNS() as ns:
        ns.register('thing', uri)
    daemon.requestLoop()
我遇到的问题是,尽管创建了一个实例,但它仅在web应用程序的第一次代理查询时创建。根据,这是正常的行为,但不是我想要的,因为第一个查询仍然很慢,因为东西的初始化

如何确保在启动守护进程后立即创建实例?

我曾考虑在守护进程的代码中创建一个代理实例,但这很棘手,因为事件循环必须正在运行

编辑


事实证明,
daemon.register()
可以接受类或对象,这可能是一种解决方案。但是,文档(上面的链接)中不建议使用此功能,而且该功能显然仅用于向后兼容。

在Pyro代码之外执行任何需要的初始化。把它藏在某个地方。使用
@behavior
装饰器的
instance\u creator
参数可以最大限度地控制创建实例的方式和时间。您甚至可以考虑预先创建服务器实例,如果需要的话,可以从池中检索一个实例。无论如何,一种可能的方法是:

import Pyro4

def slow_initialization():
    print("initializing stuff...")
    import time
    time.sleep(4)
    print("stuff is initialized!")
    return {"initialized stuff": 42}


cached_initialized_stuff = slow_initialization()


def instance_creator(cls):
    print("(Pyro is asking for a server instance! Creating one!)")
    return cls(cached_initialized_stuff)


@Pyro4.behavior(instance_mode="percall", instance_creator=instance_creator)
class Server:
    def __init__(self, init_stuff):
        self.init_stuff = init_stuff

    @Pyro4.expose
    def work(self):
        print("server: init stuff is:", self.init_stuff)
        return self.init_stuff


Pyro4.Daemon.serveSimple({
    Server: "test.server"
})
但是您的场景并不需要这种复杂性,只需初始化(这需要很长时间)并将其缓存到某个地方即可。不要每次创建新的服务器对象时都重新初始化它,只需参考缓存的预初始化结果即可。像这样的东西

import Pyro4

def slow_initialization():
    print("initializing stuff...")
    import time
    time.sleep(4)
    print("stuff is initialized!")
    return {"initialized stuff": 42}


cached_initialized_stuff = slow_initialization()


@Pyro4.behavior(instance_mode="percall")
class Server:
    def __init__(self):
        self.init_stuff = cached_initialized_stuff

    @Pyro4.expose
    def work(self):
        print("server: init stuff is:", self.init_stuff)
        return self.init_stuff


Pyro4.Daemon.serveSimple({
    Server: "test.server"
})