处理Django中用户触发的任务的最佳方法(如导入数据)

问题描述 投票:0回答:1

我需要您对我面临的挑战发表意见。我正在建立一个网站,使用Django作为后端,使用PostgreSQL作为我的数据库,使用GraphQL作为我的API层,使用React作为我的前端框架。网站托管在Heroku上。我编写了一个python脚本,该脚本可以将我登录到gmail帐户,并根据预定义的条件解析几封电子邮件,然后将解析后的数据存储到Google表格中。现在,我希望脚本成为我的网站的一部分,用户可以在其中指定确切需要解析的内容(即过滤器),然后将解析后的数据显示在表格中以查看解析任务的准确性。

我需要帮助的部分是如何设计这样的工作流程。经过一番谷歌搜索后,下面是一些我能想到的想法:

  1. 生成一个将一个“任务”存储到任务模型中的graphQL突变。一旦存储了新的任务条目,Django Signal将触发脚本。尚不确定Signal是否可以运行自定义python函数,但从我到目前为止所读的内容来看,这似乎是可行的。
  2. 使用Celery异步运行此任务。但是我不确定异步任务是否是我要执行的任务,因为我需要在用户从前端触发功能后立即运行此任务。但是我可能在这里错了。我也不确定是否需要Redis来存储任务详细信息,或者我可以在PostgreSQL上执行此操作。

实现此功能的最佳做法是什么?任务可以是任何东西,不必解析电子邮件。它也可以从excel导入数据。用户生成的任何任务,而不是计划或重复的任务。

如果这个问题对你们中的某些人来说微不足道,我先感到抱歉。我不是专业开发人员,因此上述项目是我提高技术技能和学习新技术的一种方式。

期待从您的经验中学习。

python django graphql django-celery
1个回答
0
投票

您可以将问题分解为以下步骤:

  1. 用户指定任务参数
  2. 系统执行任务
  3. 系统向用户显示结果

您可以执行所有这些操作:

  1. 一键顺序和同步;或
  2. 异步逐步操作。

同步

您可以在生成响应时运行脚本,但是它具有以下缺点:

  1. 服务器中处理您的请求的过程将阻塞,直到脚本完成为止。这可能会或可能不会影响同一服务器对其他请求的处理(这将取决于正在处理的并发请求数,脚本的工作量等)
  2. 如果脚本花费的时间太长,客户端(例如您的浏览器)甚至服务器可能会超时。您可以通过适当配置服务器在某种程度上解决此问题。

然而,这种方法的优点在于它很简单。为此,您可以仅通过请求传递参数,服务器解析并执行脚本,然后返回结果。

无需设置消息队列,任务计划程序或任何所需的程序。

异步

尽管理想情况下,对于长时间运行的任务,最好在通常的请求-响应循环之外执行此操作,以获取以下优点:

  1. 响应请求的服务器实际上可以处理其他请求。
  2. 某些脚本可能要花一些时间,有些甚至不知道脚本是否会完成
  3. 脚本不再取决于网络的可靠性(假设运行expensive任务,则您的Internet连接将跳过或只是断断续续;您将无能为力)]

这样做的缺点是您现在必须设置更多的东西,这增加了项目的复杂性和故障点。

生产者-消费者

无论您选择什么,通常最好遵循生产者-消费者模式:

  1. 生产者创建任务并将其放入队列
  2. 消费者从队列中获取任务并执行它

生产者基本上就是您,用户。您指定任务以及该任务中涉及的参数。

此队列可以是任何数据存储:像Redis这样的内存中数据存储;像RabbitMQ这样的消息传递队列;或诸如PostgreSQL之类的关系数据库管理系统。

使用者是您执行这些任务的脚本。运行使用者/脚本的方式有多种:通过您提到的Celery,它运行多个工作程序来执行通过队列传递的任务;通过一个简单的基于时间的作业调度程序(例如crontab);甚至您手动触发脚本]

这个问题实际上并不简单,因为解决方案取决于您实际要执行的任务。最好评估约束条件,参数和实际任务,以决定选择哪种方法。

但是只是为了给您提供更相关的指导:

请保持简单,除非您有令人信服的理由(例如,服务器已瘫痪,或者实际上互联网连接不可靠),否则实际上没有理由花哨。

任务越阻塞,任务花费的时间越长,或者通过网络对第三方API的依赖程度越高,将其推送到后台进程以增加可靠性和弹性就越有意义。

© www.soinside.com 2019 - 2024. All rights reserved.