重用Ruby中的线程之间的连接/替换Net :: HTTP :: Persistent

时间:2012-08-28 21:00:12

标签: ruby multithreading thread-safety net-http

我正在运行一个多线程守护进程,其中ruby Mechanize的实例(包含一个Net :: HTTP :: Persistent对象)可能会被许多线程中的一个使用并运行。我遇到了很多问题,因为Net :: HTTP :: Persistent为每个运行它的线程打开一个新的连接,所以如果我有50个线程,我最终会打开50倍以上的连接。我需要!我已经尝试了子类化和修补Net :: HTTP :: Persistent来存储它的连接信息作为其类的一部分而不是Thread.current,但后来我一直在

too many connection resets (due to Broken pipe - Errno::EPIPE)
到处都是..有什么想法吗?任何人都知道我可以使用Net :: HTTP :: Persistant的替代库,并希望能够轻松地修补Mechanize?

2 个答案:

答案 0 :(得分:1)

问题是,如果从另一个线程访问Net::HTTP::Persistent对象,并且该对象处于某个中间位置,该线程将不得不阻塞(停止执行并等待对象执行它的操作)需要),或者创建一个新的对象并弄乱它。使用线程,您可以在(请原谅我,我在这里做出假设)HTTP请求的中间,突然之间,另一个线程想要使用相同的连接创建HTTP请求,这会破坏一切(可能为什么你有连接重置问题。)

如果您真的想要线程化,那么您的选择是打开多个连接,或等待打开连接以便您可以使用它。

答案 1 :(得分:1)

恢复到Mechanize 1.0.0,这解决了问题。与1.0版中的机器人2+使用的Net :: HTTP :: Persistent不同,Persitant连接在1.0中以更可靠,多线程友好的方式处理。我的建议:坚持使用Mechanize 1.0它更可靠,错误更少,并且有多线程代码存在疯狂问题!啧。

注意:与一些评论可能建议不同,Mechanize 1.0 DOES实现持久连接:查看源代码,或使用Wireshark验证。