如何同步一些Flask式资源?

2024-10-03 00:32:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Flask RESTful API,它充当TCP设备的网关,这些设备无法处理对它们的异步调用。你知道吗

因为对我来说Resource对象只是生成的,所以我不能从一个源点对它们进行排队和管理。你知道吗

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

问题是,当发出异步请求时,第一个Resource会得到一个空列表,并附加到它,当它仍在执行时,会为第二个请求创建第二个Resource。第二个Resource实例也得到一个空列表。因此,我实际上无法使Resource实例共享一个列表。你知道吗

我在getput方法中尝试了这个方法,没有使用装饰器,而是显式地使用在数据库模型对象上定义的锁,或者使用一个公共处理程序对象来管理用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被未经编辑地获取。你知道吗

有没有办法解决这个异步同步转换?你知道吗


Tags: 对象inid列表getdefwithload
1条回答
网友
1楼 · 发布于 2024-10-03 00:32:17

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

相关问题 更多 >