【发布时间】:2021-08-20 03:54:13
【问题描述】:
我是 django 的初学者。
我想在后台继续在 django 中运行长进程。
除非我明确结束该过程,否则我希望它继续运行。
我不知道在哪里以及如何将以下代码添加到 django。
import threading
import asyncio
class long_task:
def __init__(self):
self.continue_flag = True
async def long_task(self,):
print('long task start...')
i = 0
while self.continue_flag:
print(i)
await asyncio.sleep(3)
i = i+1
def stop(self):
self.continue_flag = False
def run_loop(loop):
asyncio.set_event_loop(loop)
print('main loop start...')
loop.run_forever()
def ask_loop_stop(loop):
print("main loop stop")
loop.call_soon_threadsafe(loop.stop)
loop = asyncio.get_event_loop()
threading.Thread(target=run_loop, args=(loop,)).start()
print('main loop is ready')
long_task_1 = long_task()
asyncio.run_coroutine_threadsafe(long_task_1.long_task(), loop)
我会详细说明我想做什么。
- django 启动时运行一个循环。
- 在任何给定时间将 long_task 添加到循环中(当特定事件 通过监视外部站点发生)。
- 保持程序在后台运行,以便网站可以 看过。将来我想展示这个结果 页面上的程序。
- 在其他时间关闭循环(在维护期间)。
这是我尝试过的
- 使用 celery 和 celery-beat 注册并作为任务执行。
=>
无法指定程序在 django 启动时应该运行
- 在 django 中创建自定义任务并使用命令运行它。
.
class Command(BaseCommand):
help = "Start Main Loop"
def add_arguments(self, parser):
parser.add_argument('-i', default=1, type=int, help='UserId')
def handle(self, *args, **options):
id = options['i']
print("UserId:{},".format(id))
loop = asyncio.get_event_loop()
threading.Thread(target=run_loop, args=(loop,)).start()
print('main loop is ready')
=> 我收到以下错误,无法运行。
”django.core.exceptions.SynchronousOnlyOperation:您不能从异步上下文中调用它 - 使用线程或 sync_to_async。”
我也不知道当我启动 django 时我能做什么。
- 将代码添加到 init.py。
.
import asyncio
import threading
import time
from app import long_task
loop = asyncio.get_event_loop()
threading.Thread(target=long_task.run_loop, args=(loop,)).start()
print('main loop is ready')
=>
我收到以下错误,无法运行。
“您不能从异步上下文中调用它 - 使用线程或 sync_to_async。”
--环境--
- Windows10 64 位
- Python (3.7)
- Redis 服务器 (3.0.504)
- Django (3.2.3)
- 芹菜 (5.0.5)
- django-celery-beat (2.2.0)
- django-celery-results (2.0.1)
- PostgreSQL (13)
请告诉我如何做到这一点。
【问题讨论】:
标签: python django celery python-asyncio python-multithreading