将脚本功能卸载到响应后:方法和最佳实践?

发布于 2024-08-07 03:31:12 字数 1420 浏览 10 评论 0原文

首先,

设置:

我有一个脚本,该脚本在用户点击“上传”按钮后执行多项任务,该按钮向脚本发送所需的数据。现在,这部分目前是强制性的,我们目前无法选择从实时源中删除上传和绘制。

这一段故意啰嗦来说明一个观点。如果您讨厌这样,请跳过

现在,数据是使用正则表达式从一个非常时髦的源中解析出来的,然后分解为一个数组。然后,它检查数据库中是否存在已上传数据的日期范围内的任何数据。如果数据库中不存在数据日期范围,它会插入数据并向用户输出成功(还有一些安全检查、数据源验证和基本上传验证)...如果数据确实存在,然后,该脚本获取数据库中已有的数据,查找两组之间的差异,删除不匹配的旧数据,添加新数据,然后向受这些更改影响的每个人发送一封电子邮件(每个人一封电子邮件)在上述电子邮件中进行所有相关更改的人,这是另一个步骤)。电子邮件地址是通过 LDAP 搜索来提取的,因为我们的数据库有他们的工作电子邮件,但 LDAP 有他们的个人电子邮件,这确保他们在第二天进来之前收到电子邮件,并且不知情。最后,数据上传者被告知“已进行更改,电子邮件已发送”。这才是他们真正关心的。

现在,我可能会添加一个 Google Calendar API,将数据(当它是日程安排数据时)发布到用户的 Google Calendar。我会通过他们的工作日历来完成这件事,但我想在为 Exchange 设置 WebDav 系统之前我应该​​先熟悉一下 Google 的 API。

现在!

实际问题

此时,在 Google 集成之前,脚本最多需要一秒半的时间来运行。这是相当令人印象深刻的,至少我是这么认为的(服务器,而不是我的编码)。但在测试中,谷歌的速度却很慢。我们或许可以解决这个问题,但它提出了一个更大的问题……

在用户确认数据库已更新后,卸载部分工作的最佳方法是什么?这是他最关心的部分,也是最关键的部分。电子邮件通知和 Google 日历更新只是为了那些受上传影响的人的利益,如果这些通知有问题,他会听到(然后我也会听到),无论脚本如何讲述他先。

那么有没有一种方法,例如,运行由脚本上次执行触发的 cronjob? PHP 可以创建具有 exec() 功能的 cronjobs 吗?是否有一些标准化的方法来处理需要完成的执行后工作?

对此的任何建议都非常感激。我觉得脚本的臃肿反映了我的开发阶段以及我最终知道如何在网络应用程序中进行分工的需要。

但我也担心这没有完成,因为用户需要知道所有任务何时完成等。所以这就提出了:

最佳实践/更主观的问题

基本上,是否有一个想法,进度条,真实的-时间卸载以及其他让用户束缚于脚本的方法——当然,当与代码优化相结合时——更好、更受欢迎的方法,然后简单地说“我们已经完成了你的部分,如果你需要我们,我们会通知用户”等等。

有什么大的事情需要避免吗(除了明显不给用户任何反馈之外)?

感谢您的阅读。编码部分至关重要,因此不要觉得有必要覆盖第二部分或忘记覆盖编码部分!

First,

the set up:

I have a script that executes several tasks after a user hits the "upload" button that sends the script the data it need. Now, this part is currently mandatory, we don't have the option at this point to cut out the upload and draw from a live source.

This section intentionally long-winded to make a point. Skip ahead if you hate that

Right now the data is parsed from a really funky source using regex, then broken down into an array. It then checks the DB for any data already in the uploaded data's date range. If the data date ranges don't already exist in the DB, it inserts the data and outputs success to the user (there is also some security checks, data source validation, and basic upload validation)... If the data does exist, the script then gets the data already in the DB, finds the differences between the two sets, deletes the old data that doesn't match, adds the new data, and then sends an email to each person affected by these changes (one email per person with all relevant changes in said email, which is a whole other step). The email addresses are pulled by means of an LDAP search as our DB has their work email but the LDAP has their personal email which ensures they get the email before they come in the next day and get caught unaware. Finally, the data-uploader is told "Changes have been made, emails have been sent." which is really all they care about.

Now I may be adding a Google Calendar API that posts the data (when it's scheduling data) to the user's Google Calendar. I would do it via their work calendar, but I thought I'd get my toes wet with Google's API before dealing with setting up a WebDav system for Exchange.

</backstory>

Now!

The practical question

At this point, pre-Google integration, the script takes at most a second and a half to run. It's pretty impressive, at least I think so (the server, not my coding). But the Google bit, in tests, is SLOOOOW. We can probably fix that, but it raises the bigger question...

What is the best way to off-load some of the work after the user has gotten confirmation that the DB has been updated? This is the part he's most concerned with and the part most critical. Email notifications and Google Calendar updates are only there for the benefit of those affected by the upload, and if there is a problem with these notifications, he'll hear about it (and then I'll hear about it) regardless of the script telling him first.

So is there a way, for example, to run a cronjob that's triggered by a script's last execution? Can PHP create cronjobs with exec() ability? Is there some normalized way of handling post-execution work that needs getting done?

Any advice on this is really appreciated. I feel like the scripts bloated-ness reflects my stage of development and the need for me to finally know how to do division-of-labor in web apps.

But I also get worried that this is not done, as user's need to know when all tasks are completed, etc. So this brings up:

The best-practices/more-subjective question

Basically, is there an idea that progress bars, real-time offloading, and other ways of keeping the user tethered to the script are --when combined with optimization of the code, of course-- the better, more-preferred method then simply saying "We're done with your part, if you need us, we'll be notifying users" etc etc.

Are there any BIG things to avoid (other than obviously not giving the user any feedback at all)?

Thanks for reading. The coding part is crucial, so don't feel obliged to cover the second part or forget to cover the coding part!

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

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

发布评论

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

评论(2

静谧幽蓝 2024-08-14 03:31:12

cron 作业对此很有用。如果当用户上传数据时您只想说“嘿用户,感谢您提供的数据!”那么就可以了。

如果您更喜欢更直接的方法,则可以使用 exec() 启动后台进程。在 Linux 环境中,它看起来像这样:

exec("php /path/to/your/worker/script.php >/dev/null &");

& 部分表示“在后台运行我”。 >/dev/null 部分将输出重定向到黑洞。至于处理所有错误并通知适当的各方——这一切都取决于工作脚本的设计。

如需更灵活的跨平台方法,请查看此 PHP 手册帖子< /a>

A cron job is good for this. If all you want to do when a user uploads data is say "Hey user, thanks for the data!" then this will be fine.

If you prefer a more immediate approach, then you can use exec() to start a background process. In a Linux environment it would look something like this:

exec("php /path/to/your/worker/script.php >/dev/null &");

The & part says "run me in the backgound." The >/dev/null part redirects output to a black hole. As far as handling all errors and notifying appropriate parties--this is all down to the design of your worker script.

For a more flexible cross-platform approach, check out this PHP Manual post

绮烟 2024-08-14 03:31:12

有很多方法可以解决这个问题。您可以像上面所说的那样执行 exec(),但如果提交点击次数过多,您可能会遇到 DoS 情况。 pcntl 扩展可以说更擅长管理这样的流程。查看 这篇文章 查看讨论(共有 3 部分)。

您可以使用 Javascript 发送第二个 ajax 帖子,然后运行适当的工作脚本。通过使用ignore_user_abort()并发送Content-Length,浏览器可以提前断开连接,但您的apache进程将继续运行并处理您的数据。优点是没有 forkbomb 的潜力,缺点是它会打开更多的 apache 进程。

另一种选择是在后台使用 cron,它会查看进程队列表以了解“稍后”要做的事情 - 您将项目粘贴到前端的此表中,在处理时在后端将它们删除(请参阅 Zend_Queue)。

另一种方法是使用更加分布式的作业框架,例如 gearmand - 它可以处理其他计算机上的项目。

这一切都取决于您的整体能力和要求。

There are a number of ways to go about this. You could exec(), like the above says, but you could potentially run into a DoS situation if there are too many submit clicks. the pcntl extension is arguably better at managing processes like this. Check out this post to see a discussion (there are 3 parts).

You could use Javascript to send a second, ajax post that runs the appropriate worker script afterwards. By using ignore_user_abort() and sending a Content-Length, the browser can disconnect early, but your apache process will continue to run and process your data. Upside is no forkbomb potential, Downside is it will open more apache processes.

Yet another option is to use a cron in the background that looks at a process-queue table for things to do 'later' - you stick items into this table on the front end, remove them on the backend while processing (see Zend_Queue).

Yet another is to use a more distributed job framework like gearmand - which can process items on other machines.

It all depends on your overall capabilities and requirements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文