Jav*_*ock 10 python gunicorn falconframework rx-py
我使用Falcon实现了一个Web服务.此服务存储状态机(pytransitions),该状态机将传递给构造函数中的服务资源.该服务与gunicorn一起运行.
Web服务启动使用RxPy的过程.在其中返回的事件on_next(event)用于触发状态机中的转换.
错误
我希望状态机在服务和资源中都具有一致的状态,但似乎在资源中状态永远不会改变.
我们有一个试图重现这种行为的测试,但令人惊讶的是测试工作
class TochoLevel(object):
def __init__(self, tochine):
self.tochine = tochine
def on_get(self, req, res):
res.status = falcon.HTTP_200
res.body = self.tochine.state
def get_machine():
states = ["low", "medium", "high"]
transitions = [
{'trigger': 'to_medium', 'source': ['low', 'medium', 'high'], 'dest': 'medium'},
{'trigger': 'to_high', 'source': ['low', 'medium', 'high'], 'dest': 'high'},
{'trigger': 'to_low', 'source': ['low', 'medium', 'high'], 'dest': 'low'}
]
locked_factory = MachineFactory.get_predefined(locked=True)
return locked_factory(
states=states,
transitions=transitions,
initial='low',
auto_transitions=False,
queued=False
)
def _level_observable(observer):
for i in range(1, 21):
sleep(0.1)
next_val = 'to_low'
if 8 <= i <= 15:
next_val = 'to_medium'
elif i > 15:
next_val = 'to_high'
observer.on_next(next_val)
observer.on_completed()
def get_level_observable():
return Observable.create(_level_observable)
class NotBlockingService(falcon.API):
def __init__(self):
super(NotBlockingService, self).__init__()
self.tochine = get_machine()
self.add_route('/tochez', TochoLevel(self.tochine))
def _run_machine(self, val):
self.tochine.trigger(val)
print('machine exec: {}, state: {}'.format(val, self.tochine.state))
return self.tochine.state
def start(self):
source = get_level_observable()
(source.subscribe_on(ThreadPoolScheduler(2))
.subscribe(self._run_machine))
def test_can_query_falcon_service_while_being_susbcribed_as_observer():
svc = NotBlockingService()
client = testing.TestClient(svc)
assert client.simulate_get('/tochez').text == 'low'
start = time()
svc.start()
sleep(1.2)
assert client.simulate_get('/tochez').text == 'medium'
end = time()
sleep(1.2)
assert client.simulate_get('/tochez').text == 'high'
assert (end - start) < 2
Run Code Online (Sandbox Code Playgroud)
问题
为什么状态机不改变资源的状态 TochoLevel,当我启动与服务gunicorn在和传播状态on_next的方法rxpy?
当您在开发模式下执行服务时,您只使用一个fork(一个执行过程).当您使用像Gunicorn这样的软件时,您正在使用预执行策略在生产环境中提供可靠的服务.
Preforking策略生成许多子进程来解析请求,逻辑是独立的,在不同请求之间以独立模式运行每个fork.
感谢Python中的WSGI标准化应用程序(Python2_PEP-333和Python3_PEP-3333),Gunicorn收到了一个APP对象.Gunicorn发布了其配置中指示的许多实例(preforks).Gunicorn称这样的叉子工人,默认情况下它使用1名工人.每个工作人员都将使用其状态,也许Gunicorn还为每个请求创建新的App对象实例...
这就是没有持久性的状态机背后的原因.
提示:首先尝试使用1个worker启动Gunicorn并检查状态机的状态持久性.如果实现状态机的持久性,要解决的第二个问题将是所有工作者的状态机同步.
| 归档时间: |
|
| 查看次数: |
248 次 |
| 最近记录: |