я следующее приложение, которое запускает планировщик периодически обновлять состояние глобальной переменной (ДИКТ):Обновление глобального Dict из нескольких потоков
from sanic import Sanic
from sanic.response import text
from apscheduler.schedulers.background import BackgroundScheduler
import bumper
app = Sanic()
scheduler = BackgroundScheduler()
inventory = {1: 1, 2: 2}
@scheduler.scheduled_job('interval', seconds=5)
def bump():
bumper.bump()
@scheduler.scheduled_job('interval', seconds=10)
def manual_bump():
global inventory
inventory[2] += 1
@app.route("/")
async def test(request):
return text(inventory)
if __name__ == "__main__":
scheduler.start()
app.run(host="0.0.0.0", port=8000)
Функция импортирован в 5-секундным интервалом задания в другом файле в том же каталоге:
from app import inventory
def bump_inventory():
inventory[1] += 1
print('new', inventory)
Это, однако, не работает, как я надеялся. Импортированная функция обновляет инвентарь, но изменение никогда не распространяется на исходный словарь, поэтому либо bump_inventory
работает с копией inventory
, либо никогда не обновляет ее за пределами области действия. В двух разных терминалах:
]$ python app.py
2017-02-19 14:11:45,643: INFO: Goin' Fast @ http://0.0.0.0:8000
2017-02-19 14:11:45,644: INFO: Starting worker [26053]
new {1: 2, 2: 2}
new {1: 3, 2: 2}
]$ while true; do curl http://0.0.0.0:8000/; echo; sleep 1; done
{1: 1, 2: 2}
...
{1: 1, 2: 3}
...
Каков правильный способ сделать это?
Спасибо! Я все еще довольно новичок в асинчио, поэтому это очень полезная информация. Причина, по которой я хочу иметь глобальное состояние, - это не беспокоиться о базе данных и хранить все в памяти. БД SQLite в памяти также является опцией, но данные в инвентаре очень просты (идеально подходят для простого потокобезопасного dict), поэтому кажется, что это избыток. В чем преимущество сохранения глобального состояния в 'app', а не как отдельной переменной? – mart1n
Кроме того, любая версия, когда релиз, который включает 'add_task', будет доступен в PyPI? – mart1n