У меня есть Flask-RESTful API, который действует как шлюз для TCP-устройств, которые не могут обрабатывать асинхронные вызовы к ним.
Поскольку для меня Resource
объекты просто появляются, я не могу ставить их в очередь и управлять ими из одной точки источника.
Я попытался создать декоратор, который будет использовать Resources
, который нуждается в синхронизации.В этом декораторе я попытался добавить идентификатор устройства TCP (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
выбирается неотредактированной.
Есть ли способ разрешить это асинхронное преобразование?