Django 以下标形式将进度保存到 Session

Django saving progress to the Session in subscript

所以我想知道这是如何正确完成的。 我尝试在 request.session 对象中保存一个长 运行 任务的进度。并且能够使用另一种查看方法

获取进程的状态

我正在使用池 Class 使我的长 运行 进度异步:

MyCalculation.py
def longrunning(x,request):
  request.session['status'] = 5;
  return x*x

views.py
def dolongrunning(request, x):
  pool = Pool(processes=1)
  result = pool.apply_async(MyCalculation.longrunning, [x, request])
  return JsonResponse(..)

def status(request):
  return JsonResponse(request.session.get('status))

所以这不起作用。我的异步作业确实执行了,但请求对象没有获得我的进度信息。

我怎样才能做到这一点,或者有其他方法吗? 我觉得传递请求对象通常不是一个好主意。 将长 运行 操作的状态存储在 Django/Python 中的最佳做法是什么?

不同的进程不共享相同的内存space但它们会为每个进程获得一份副本。

在您的例子中,工作进程在 longrunning 函数中接收到的 request 对象是在父进程中创建的对象的副本。对其中一个进程所做的更改不会影响其他进程。

您要做的是从工作进程向父进程发送更新,然后在父进程中更新请求状态。

from multiprocessing import Pool, Queue


def worker(task, message_queue):  # longrunning
    # do something
    message_queue.put(5)
    # do something else
    message_queue.put(42)


def request_handler(request, task, message_queue):  # dolongrunning
    result = pool.apply_async(worker, [task, message_queue])
    return JsonResponse(..)


def status(request):
    status = message_queue.get()  # this is blocking if no messages in queue
    request.session['status'] = status;
    return JsonResponse(request.session['status'])


pool = Pool(processes=1) 
message_queue = Queue()

这非常简单,如果没有设置状态,它实际上会阻止状态请求,但它提供了一个想法。

更好的方法是将请求存储在缓冲区中,并使用线程保持消息队列为空。每次收到状态请求时,都会返回从工作人员收到的最后一个状态更新。