当前位置: 首页 > 知识库问答 >
问题:

当金字塔正在运行进程时,如何显示“处理”或“正在进行”视图?

伊温书
2023-03-14

我已经启动并运行了一个简单的金字塔应用程序,大多数视图都是围绕sqlite数据库的一个相当薄的包装,其中包含一些表单来编辑/添加一些信息。

每月有几次,需要将新数据块添加到该系统(通过csv导入)。数据保存在一个SQL表中(整个过程直到提交需要大约4秒)。

每次上传新的数据块时,都会触发对数据库中其他表的重新计算。重新计算过程需要相当长的时间(一个月的数据大约需要21-50秒)。

目前,我只是让浏览器/客户端坐在那里等待过程完成,但我确实预见到,随着系统使用率的提高,计算过程会花费越来越多的时间。从UI的角度来看,这显然看起来像一个挂起的过程。

我可以做些什么来向用户表明:-

>

他们还要等多久(进度条等)?

注意:我并不是在这里询问长轮询或WebSocket,因为这不是一个真正的交互式应用程序,而且基于我的基本知识,WebSocket/async对于我来说太过复杂了。

我想在这一点上还有一个后续问题,我在视图函数中运行进程是不是做错了?似乎很少看到在网络上的例子/教程中这样做。在这种情况下,我应该用芹菜或类似的东西吗?

共有2个答案

严正初
2023-03-14

那么,长时间运行的过程是由浏览器操作触发的吗?也就是说,用户正在上传得到处理的CSV,然后视图就在那里进行处理?对于短时间运行的浏览器进程,我通过jQuery或javascript使用了一个加载指示器,基本上是在进程运行时弹出一个模式动画微调器或其他东西,然后当它完成隐藏微调器时。

但是,如果你进入越来越长的流程,我认为你真的应该考虑一些后台处理,将其从UI中卸载。它不必是基于消息的工作者,但即使是最终用户上传文件,并在数据库中设置“待处理”条目之类的东西。然后,可以在后台定期安排一个金字塔脚本,轮询状态表并运行它找到的任何内容。您可以将视图中的文件处理移动到单独的方法,并且可以从命令行脚本调用该方法。然后,当处理完成时,它可以更新状态表,表明它已经完成,并且反馈可以在某个地方返回给用户,而不会一直阻塞用户界面。

伊俊能
2023-03-14

你说得对,在视图函数中进行长时间的计算通常是不被允许的——我的意思是,如果这是一个典型的网站,有随机的访问者,他们能够挂一个网络服务器线程一分钟,那么这就是DoS漏洞的根源。但是在某些情况下(内部网站,很少用户,只有管理员可以访问上传csv表单),你可能会逃脱惩罚。事实上,我曾经有运行几个小时的维护脚本:)

这里的诀窍是避免浏览器超时——此时,您的客户机将数据发送到服务器,只是坐在那里等待任何回复,而不知道他们的请求是否正在被处理。通常,在大约60秒时,浏览器(或代理,或前端Web服务器)可能会变得不耐烦并关闭连接。然后,服务器进程将在尝试向已关闭的连接写入任何内容时出错,并导致崩溃/引发错误。

为了防止这种情况发生,服务器需要定期向连接写入内容,以便客户端看到服务器处于活动状态,并且不会关闭连接。

"普通"金字塔模板被缓冲-即直到生成整个模板才将输出发送到客户端。因此,您需要直接使用response.app_iter/response.body_file并定期输出一些数据。

例如,您可以从金字塔Cookbook复制Todo List Application in One File示例,并将new_view函数替换为以下代码(其本身已从本问题中借用):

@view_config(route_name='new', request_method='GET', renderer='new.mako')
def new_view(request):
    return {}


@view_config(route_name='new', request_method='POST')
def iter_test(request):
    import time

    if request.POST.get('name'):
        request.db.execute(
            'insert into tasks (name, closed) values (?, ?)',
            [request.POST['name'], 0])
        request.db.commit()


    def test_iter():
        i = 0
        while True:
            i += 1
            if i == 5:
                yield str('<p>Done! <a href="/">Click here</a> to see the results</p>')
                raise StopIteration
            yield str('<p>working %s...</p>' % i)
            print time.time()
            time.sleep(1)

    return Response(app_iter=test_iter())

(当然,这个解决方案在用户界面方面不是很花哨,但你说过你不想弄乱WebSocket和芹菜)

 类似资料:
  • 问题内容: 标准方法如下: 在这种情况下,如果跟踪当前进程(例如,使用gdb运行或附加到该进程),则ptrace返回错误。 但这有一个严重的问题:如果调用成功返回,则gdb稍后可能不会附加到它。这是一个问题,因为我没有尝试实现反调试的东西。我的目的是在满足条件(即断言失败)并且gdb正在运行时发出“ int 3”(否则,我会得到SIGTRAP来停止应用程序)。 禁用SIGTRAP并每次发出’int

  • 问题内容: 我有以下jQuery Ajax调用: 我想在进行ajax调用时显示图像。我怎样才能做到这一点? 谢谢, 问题答案: 试试这个 : 这将在您每次执行ajax请求时显示加载图像,我在页面顶部设置了该div,因此它不会阻塞页面,但是您始终可以看到ajax调用何时进行。

  • 问题内容: 如何获取Go中当前正在运行的进程的列表? 该OS软件包提供了一些功能:http : //golang.org/pkg/os/, 但没有提供任何内容来查看正在运行的进程的列表。 问题答案: 标准库中没有这样的功能,很可能永远不会。 在大多数情况下,程序不需要进程列表。Go程序通常希望等待一个或更少数量的进程,而不是所有进程。进程的PID通常通过除搜索所有进程的列表之外的其他方式获得。 如

  • 我拥有的现有代码: 我想丰富现有代码,并在收到一些不允许的数据时引发异常,我做了以下更改: 但由于以下原因,我的实现甚至不可编译: 您能为我的特定场景提供建议吗?

  • 当我的selenium程序由于某些错误而崩溃时,它似乎会留下正在运行的进程。 例如,这是我的流程列表: 这是我的代码: 有时,浏览器加载网页元素的速度不够快,所以当它试图点击它没有找到的东西时,Selenium会崩溃。其他时候它工作正常。 为了简单起见,这是一个简单的例子,但是对于一个更复杂的硒程序,什么是保证干净退出而不留下正在运行的进程的方法?它应该在意外崩溃和成功运行时干净退出。