我有一个Flask RESTful API,它充当TCP设备的网关,这些设备无法处理对它们的异步调用。你知道吗
因为对我来说Resource
对象只是生成的,所以我不能从一个源点对它们进行排队和管理。你知道吗
我试图创建一个需要同步的Resources
将使用的装饰器。在这个decorator中,我尝试将TCP设备的id(load_id
)附加到全局范围的列表中,并在处理请求后将其删除。你知道吗
问题是,当发出异步请求时,第一个Resource
会得到一个空列表,并附加到它,当它仍在执行时,会为第二个请求创建第二个Resource
。第二个Resource
实例也得到一个空列表。因此,我实际上无法使Resource
实例共享一个列表。你知道吗
我在get
、put
方法中尝试了这个方法,没有使用装饰器,而是显式地使用在数据库模型对象上定义的锁,或者使用一个公共处理程序对象来管理用load_id
唯一标识的对象上的锁,但是没有用,我总是得到一个过时的列表。你知道吗
以下是其中一个的精简版本:
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
在代码中,在第一个请求中,用#APPEND注释的行更改了其作用域中的loads_with_query_in_progress
。但是,当另一个请求被生成时,变量loads_with_query_in_progress
被未经编辑地获取。你知道吗
有没有办法解决这个异步同步转换?你知道吗
这种差异是由于生产使用uwsgi,而uwsgi使用多个进程,这导致共享对象之间存在幻象差异,因为我们在不同的进程中使用不同的对象,但我们正在调试所有日志记录到同一文件的日志记录进程。你知道吗
相关问题 更多 >
编程相关推荐