如何同步一些Flask-RESTful资源?

时间:2019-05-22 12:52:28

标签: python flask flask-restful

我有一个Flask-RESTful API,它充当无法处理异步调用的TCP设备的网关。

由于对我来说Resource对象只是生成的,所以我无法从一个源头对它们进行排队和管理。

我尝试创建需要同步的Resources使用的装饰器。在这个装饰器中,我尝试将TCP设备的ID(load_id)附加到全局范围中的列表中,并在处理请求后将其删除。

问题是,当发出异步请求时,第一个Resource会得到一个空列表,并追加到该列表中,而当它仍在执行时,第二个Resource会为第二个请求创建。第二个Resource实例也得到一个空列表。因此,我实际上不能使Resource实例共享一个列表。

我尝试在getput方法中没有装饰器的情况下显式地进行了此操作,并在数据库模型对象上定义了锁,或者在一个公共处理程序对象中管理了用{{唯一标识的对象1}},但无济于事,我总是得到一个过时的列表。

以下是其中一个的精简版本:

load_id

在此代码上,在第一个请求中,用#APPEND注释的行更改了其范围内的loads_with_query_in_progress = [] # Global scope def disallow_async_calls(func): @wraps(func) def decorator(*args, **kwargs): global loads_with_query_in_progress load_id = kwargs.get("load_id", None) load = Load.query.get(load_id) if load in loads_with_query_in_progress: # Load is in the list. Aborting. raise Exception else: loads_with_query_in_progress.append(load) # APPEND try: decorated_function_output = func(*args, **kwargs) except Exception as e: loads_with_query_in_progress.remove(load) # Expt handling cleanup raise e loads_with_query_in_progress.remove(load) # Remove lock return decorated_function_output return decorator class LoadStateAPI(Resource): decorators = [auth.login_required, disallow_async_calls] ... def get(self, load_id): load = Load.query.get(load_id) try: rqObj = RelayQueryObject(load) rqObj.execute() except: raise if(rqObj.fsmState == CommState.COMPLETED): return {'state' : rqObj.response}, 200 。但是,当产生另一个请求时,变量loads_with_query_in_progress会被未经编辑地获取。

有什么方法可以解决这种异步同步转换吗?

1 个答案:

答案 0 :(得分:0)

差异是由于生产使用uwsgi,而uwsgi使用多个进程,导致共享对象之间存在幻像差异,导致我们在不同进程中使用了不同的对象,但是我们正在调试所有日志记录的日志记录进程到同一文件。