块线程执行直到在测试python django中完成

发布于 2025-02-03 17:37:40 字数 929 浏览 2 评论 0原文

我有一个Django应用程序,需要进行一些3D服务调用以计算嵌入。这个呼叫需要时间并阻止执行,我想使其异步。为此,我正在使用线程。

class MyView():
    def create_answer_embedding(answer):
        embedding = long_computing_call(answer)
        db.write(embedding) <- pseudo code, the idea is that after creating the embedding, we create an AnswerEmbedding obj. in the db
    
    def post(request, *args, **kwargs):
        answer = request.data.get("answer")
        Thread(target=self.create_answer_embedding, args=(answer, )).start()
        return Response()

因此,线程开始计算嵌入,视图返回响应。计算完成后,将在DB中创建一个新的回答对象。

现在我需要测试它正常工作。因此,如果我只是运行一个进行API调用的测试:

response = client.post("/my-view")
answer_embedding = AnswerEmbedding.objects.get(answer__id=response.json()['id'])

此测试会失败,因为它在实际创建线程中创建之前检查了Answerembedding.objects.get

因此,我需要以某种方式使此线程运行同步或找到正确模拟它的方法。我只能模拟该线程,但是这样,测试将无法检查是否创建了嵌入。

有什么想法吗? 谢谢

I have a Django app that needs to make some 3d service call to compute embedding. This call takes time and blocking execution and I want to make it async. For this I am using Thread.

class MyView():
    def create_answer_embedding(answer):
        embedding = long_computing_call(answer)
        db.write(embedding) <- pseudo code, the idea is that after creating the embedding, we create an AnswerEmbedding obj. in the db
    
    def post(request, *args, **kwargs):
        answer = request.data.get("answer")
        Thread(target=self.create_answer_embedding, args=(answer, )).start()
        return Response()

So the thread starts calculating embedding and the view returns a response. Once calculating is finished, a new AnswerEmbedding object is created in the DB.

Now I need to test it works properly. So if I just run a test that makes an api call:

response = client.post("/my-view")
answer_embedding = AnswerEmbedding.objects.get(answer__id=response.json()['id'])

This test fails because it checks AnswerEmbedding.objects.get before it is actually created in the Thread.

So, I need to somehow either make this Thread running sync or find a way to properly mock it. I could just mock the Thread but with this the test will not check if the embedding is created or not.

Any ideas?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

祁梦 2025-02-10 17:37:40

我想知道,使用线程有什么意义?

如果您仍然想阻止它,我认为您可以使用join()

class MyView():
    def create_answer_embedding(answer):
        embedding = long_computing_call(answer)
        db.write(embedding)
    
    def post(request, *args, **kwargs):
        answer = request.data.get("answer")
        th = Thread(target=self.create_answer_embedding, args=(answer, ))
        th.start()
        th.join()
        return Response()

,或者您的问题在等待嵌入要创建的

class MyView():
    is_embedding_created = False

    def create_answer_embedding(answer):
        embedding = long_computing_call(answer)
        MyView.is_embedding_created = True
        db.write(embedding)
        MyView.is_embedding_created = False
    
    def post(request, *args, **kwargs):
        answer = request.data.get("answer")
        Thread(target=self.create_answer_embedding, args=(answer, )).start()
        while not MyView.is_embedding_created:
            time.sleep(0.1) # use a delay while waiting to reduce resource consumption
        return Response()

I'm wondering, What's the point of using thread?

if you still want to block it, I think you could use join()

class MyView():
    def create_answer_embedding(answer):
        embedding = long_computing_call(answer)
        db.write(embedding)
    
    def post(request, *args, **kwargs):
        answer = request.data.get("answer")
        th = Thread(target=self.create_answer_embedding, args=(answer, ))
        th.start()
        th.join()
        return Response()

or if your problem is waiting the embedding to be created you can use state checker

class MyView():
    is_embedding_created = False

    def create_answer_embedding(answer):
        embedding = long_computing_call(answer)
        MyView.is_embedding_created = True
        db.write(embedding)
        MyView.is_embedding_created = False
    
    def post(request, *args, **kwargs):
        answer = request.data.get("answer")
        Thread(target=self.create_answer_embedding, args=(answer, )).start()
        while not MyView.is_embedding_created:
            time.sleep(0.1) # use a delay while waiting to reduce resource consumption
        return Response()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文