问题标签 [anyevent]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
593 浏览

perl - 如何从回调中调用事件循环?

也就是让事件循环处理当前队列中的事件。在 VBA 中,调用名为DoEvents.

我想在 Perl 中做到这一点。最好在 AnyEvent 中执行此操作,因为我有一个用它编写的脚本。但我在文档中找不到任何类似的功能。

我天真地尝试用 condvar 实现它,因为文档说recv调用事件循环,但它失败了,这里是示例代码:

输出是:

更新: AnyEvent.pm 中有几行:

如果您对它们发表评论,则 DoEvents() 有效。

但是,最好有不涉及修改此 CPAN 模块的解决方案。

0 投票
2 回答
322 浏览

perl - 将类子例程作为回调传递

我正在使用一个接受回调的模块(AnyEvent::Socket)。我正在尝试将类子例程作为回调传递,但没有任何工作示例:

它只是不起作用,它抱怨未定义的变量。如果我将函数作为匿名子例程传递,它可以工作

0 投票
2 回答
86 浏览

perl - 使用 perl AnyEvent 测量单个时间

我需要获取许多 http url,我使用 AnyEvent::HTTP 来执行此操作对于每个 URL 我需要测量所花费的时间我该怎么做?

我的代码(精简)在这里

0 投票
1 回答
228 浏览

perl - 如何强制 AnyEvent 使用 EV

我一直在使用 AnyEvent 并且 EV 已安装在我的计算机中。

我的理解是,如果安装了 EV,AnyEvent 将尝试将其用作第一选择,但我一直看到人们这样做:

0 投票
2 回答
370 浏览

perl - 如何使用 Perl 的 AnyEvent::RabbitMQ 正确断开与 RabbitMQ 的连接?

我想以适当的方式断开与 RabbitMQ 的连接。通过查看Perl 的AnyEvent::RabbitMQ(我正在使用)的源代码,我发现似乎关闭所有打开到 RabbitMQ 的通道的方法。close

所以我

  1. 连接到 RabbitMQ
  2. 开通了渠道
  3. 宣布交换
  4. 绑定到那个交易所
  5. 声明了一个队列
  6. 绑定到那个队列
  7. 在实例(不是实例)上执行close方法AnyEvent::RabbitMQ::Channel

连接似乎已关闭,但 RabbitMQ 日志显示“AMQP 连接”为“connection_closed_abruptly”。

这是该连接的完整 RabbitMQ 日志:

这是示例代码:

如何使用 Perl 正确断开与 RabbitMQ 的连接AnyEvent::RabbitMQ

0 投票
1 回答
2683 浏览

perl - 保持 perl 脚本运行

我有一个使用 AnyEvent::MQTT 订阅消息队列的 perl 脚本。

目前我想做的就是在收到消息时打印出来。我对 perl 完全陌生,所以我使用它附带的演示代码,其中包含一些将 STDIN 上的任何内容作为消息发布的位 - 这很好用,我可以看到收到的所有消息。

此代码如下所示

我遇到的问题是,如果我在评论后删除所有内容,publish line-by-line from file handle那么我的应用程序一运行就会退出。

我尝试过包含一个休眠 5 秒但不起作用的 while 循环(该应用程序看起来就像挂起)。

我知道我需要做一些事情来告诉应用程序只是为了保持活力和冷静,但我不知道那个命令是什么:-)

0 投票
1 回答
482 浏览

multithreading - 如何在 Perl 中处理 AnyEvent、RabbitMQ(心跳)和长时间运行的作业?

我正在实现一个分布式 cronjob 执行系统(所谓的cron 计算集群)。当操作时间到了时,Cronjobs 应该排队到消息队列 (RabbitMQ) 中。另一方面(集群的节点/工作人员)是一个 Perl 守护进程AnyEvent::RabbitMQ,用于从消息队列中接收一个 cronjob/task/消息,处理该任务并从消息队列中请求另一个恰好一个 cronjob/task/消息,然后很快。

我使用 RabbitMQ 的心跳功能AnyEvent::RabbitMQ来帮助 RabbitMQ 识别断开的连接。

没关系心跳间隔的实际值!我也有很长的工作需要几天的时间。因此,将间隔设置为最长的 cronjob 将不是一种选择。

请参阅以下代码片段以在 Perl 守护进程工作程序中执行实际的 cronjob。它是在“AnyEvent->timer”中实现的,不会对消息执行 DoSing RabbitMQ。使用此方法是因为 RabbitMQconsume被禁止(被管理)。

progress_job()是解析消息并执行作业的位置。pause_timer()resume_timer()控制AnyEvent->timer触发_timer_tick()

第一个长时间运行的作业进入,系统“崩溃”并显示各种错误消息。有时它会抛出“未知频道 ID:1”,有时它会抛出“频道已关闭”。所以我做了“愚蠢的调试”(试图弄乱配置),发现当heartbeat间隔短于progress_job()这些错误中所用的时间时,会抛出这些错误。经过一番思考,这是有道理的。progress_job()是一个阻塞子程序,AnyEvent 无法继续向 RabbitMQ 发送心跳包。

我对解决阻塞-heatbeat 问题的第一个快速想法是progress_job()在子进程中分叉并执行。FORK 上的 AnyEvents 文档指出,fork当子进程无法访问事件系统(例如通过 AnyEvent)时,它可以保存以供使用。下一个想法:好的,没有访问事件系统的权限,所以我可以做 fork。但是:计时器应该在返回resume_timer()后恢复()progress_job()。理论上resume_timer()会在返回之后fork()而不是之后调用。progress_job()所以我停止了我的实施。

我的问题:如何解决最后一点?如何resume_timer()progress_job()(或换句话说分叉的孩子)返回之后?resume_timer()由于分叉和事件系统不是线程安全的,我无法放入孩子中。

0 投票
2 回答
940 浏览

perl - 在特定示例中了解 perl 中的异步

我必须编写一个脚本来并行获取一些 URL 并做一些工作。过去我一直使用Parallel::ForkManager这些东西,但现在我想学习一些新东西并尝试使用AnyEvent(和AnyEvent::HTTPAnyEvent::Curl::Multi)进行异步编程......但我在理解 AnyEvent 和编写一个脚本时遇到了问题,应该:

  • 打开一个文件(每一行都是一个单独的 URL)
  • (从现在开始并行,但限制 fe 10 个并发请求)
  • 逐行读取文件(我不想将整个文件加载到内存中 - 它可能很大)
  • 对该 URL 发出 HTTP 请求
  • 读取响应
  • 相应地更新 MySQL 记录
  • (下一个文件行)

我已经阅读了许多手册、教程,但我仍然很难理解阻塞代码和非阻塞代码之间的区别。我在http://perlmaven.com/fetching-several-web-pages-in-parallel-using-anyevent找到了类似的脚本,Szabo 先生在其中解释了基础知识,但我仍然无法理解如何实现类似的东西:

...并在这种情况下添加并发限制。

我将非常感谢您的帮助;)

更新

按照池上的建议,我Net::Curl::Multi试了一下。我对结果非常满意。经过多年Parallel::ForkManager仅用于并发抓取数千个 URL 之后,Net::Curl::Multi这似乎很棒。这是我while在文件句柄上带有循环的代码。它似乎可以正常工作,但考虑到这是我第一次写这样的东西,我想请更有经验的 Perl 用户看看并告诉我是否有一些潜在的错误,我错过的东西等等。另外,如果我可能会问:由于我不完全理解Net::Curl::Multi并发的工作原理,请告诉我是否应该预期将 MySQL UPDATE 命令(通过DBI)放入RESPONSE循环中会出现任何问题(显然除了更高的服务器负载 - 我希望最终脚本运行大约 50 个并发N::C::M工作人员,也许更多)。

0 投票
2 回答
375 浏览

perl - Perl Anyevent,非阻塞redis推送

我有下面的代码来执行非阻塞 rpush 到 redis 服务器当我只运行 1 rpush 时,代码工作正常但是当我在 while 循环中运行它时,脚本在第一次执行后挂起。为什么 ?

0 投票
2 回答
572 浏览

perl - 如果间隔计时器事件总是准备好,为什么 AnyEvent::child 回调永远不会运行?

更新此问题可以使用https://github.com/zbentley/AnyEvent-Impl-Perl-Improved/tree/io-starvation中的修复程序来解决

语境:

我正在将 AnyEvent 与一些其他同步代码集成。同步代码需要安装一些观察者(在计时器、子进程和文件上),等待至少一个观察者完成,做一些同步/阻塞/遗留的事情,然后重复。

我正在使用基于纯 perlAnyEvent::Loop的事件循环,这对于我的目的来说已经足够了;我需要它的大部分是信号/过程/定时器跟踪。

问题:

如果我有一个可以暂时阻止事件循环的回调,则子进程退出事件/回调永远不会触发。最简单的例子,我可以让手表成为一个子进程并运行一个间隔计时器。间隔计时器在完成之前会做一些阻塞:

这段代码让子进程变得僵化,并一遍又一遍地打印“计时器”,“永远”(我运行了几分钟)。如果sleep 1从计时器的回调中删除调用,则代码可以正常工作,并且子进程观察程序会按预期触发。

我希望孩子观察者最终会运行(在孩子退出后的某个时刻,事件队列中的任何间隔事件都会运行、阻塞和完成),但事实并非如此。

sleep 1可以是任何阻塞操作。它可以用忙碌等待或任何其他需要足够长时间的东西来代替。它甚至不需要花一秒钟;它似乎只需要 a) 在子退出事件/SIGCHLD 传递期间运行,并且 b) 导致间隔始终要根据挂钟运行。

问题:

为什么 AnyEvent 从来没有运行我的子进程观察者回调?

如何将子进程退出事件与可能阻塞很长时间以致下一个间隔到期的间隔事件多路复用?

我试过的:

我的理论是,由于在事件循环之外花费的时间而变得“就绪”的计时器事件可以无限期地抢占 AnyEvent 内某处的其他类型的就绪事件(如子进程观察者)。我尝试了几件事:

  • 使用AnyEvent::Strict不会以任何方式显示任何错误或改变行为。
  • 部分解决方案:在任何时候删除间隔事件确实会使子进程观察程序触发(好像在 AnyEvent 内部完成了一些内部事件轮询/队列填充,只有当没有计时器事件根据挂钟“准备好”时才会发生)。缺点:在一般情况下不起作用,因为我必须知道我的子进程何时退出才能知道何时推迟我的间隔,这是重言式的。
  • 部分解决方案:与子进程观察者不同,其他间隔计时器似乎能够相互多路复用,所以我可以waitpid在另一个间隔计时器中安装手动调用来检查和获取子进程。缺点:子等待可以人为延迟(我的用例涉及大量频繁的进程创建/销毁),任何已安装并成功触发的AnyEvent::child观察者将自动收割子,而不告诉我的间隔/waitpid计时器,需要编排,和通常感觉就像我在滥用 AnyEvent。