我已经做了很多的发展在C#/.Net和异步的故事一直存在从一开始(诚然API的已超过从开始/结束事件的年显著改变,以Task<T>用async/ await).在过去一年左右的时间里,我一直在使用Node.js进行开发,它以异步方式执行所有I/O并使用单线程事件循环模型.最近我正在开发一个我们使用Ruby的项目,对于应用程序的一部分,我觉得以异步方式制作一大堆Web请求是有意义的,并且惊讶地发现Ruby中的异步故事非常多不同.执行任何异步I/O的唯一方法是使用EventMachine.
我的问题归结为:为什么在.Net(以及我可以告诉它对Java/JVM也是如此)不需要事件循环,我可以随时触发异步请求但是在像Ruby/Python这样的语言中,我需要分别使用eventmachine/twisted?我觉得有一些关于异步I/O如何工作的基本问题,我不理解.
我有一台新的 m1 mac,但无法安装eventmachinegem,完整日志如下。
我尝试了这些解决方案:
\n同样的错误。
\n一些信息:
\n $ sw_vers\nProductName: macOS\nProductVersion: 12.2\nBuildVersion: 21D49\n\n $ bundle --version\nBundler version 2.1.4\nRun Code Online (Sandbox Code Playgroud)\n和错误:
\n $ gem install eventmachine -v \'1.2.7\' \nRun Code Online (Sandbox Code Playgroud)\nem.cpp:706:13: error: use of undeclared identifier \'rb_thread_select\'; did you mean \'rb_thread_fd_select\'?\n if ((ret = rb_thread_select(kqfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {\n …Run Code Online (Sandbox Code Playgroud) 我一直在研究用EventMachine来处理一些工作的可能性.在Sinatra中,这似乎工作得很好,但Rails 3似乎在渲染视图之前执行所有刻度.
当我在瘦Web服务器下运行以下代码时,它的行为与预期一致.第一个请求立即返回,第二个请求正在等待3秒睡眠呼叫完成.这是预期的行为.
class EMSinatra < Sinatra::Base
get "/" do
EM.next_tick { sleep 3 }
"Hello"
end
end
Run Code Online (Sandbox Code Playgroud)
在Rails 3运行中,我正在尝试做同样的事情:(在瘦下运行)
class EmController < ApplicationController
def index
EM.next_tick {
sleep(3)
}
end
end
Run Code Online (Sandbox Code Playgroud)
在Rails中,睡眠调用在将视图呈现给浏览器之前发生.结果是我等待3秒钟才能渲染初始页面.
有人知道为什么会这样吗?我不是在寻找评论,这是一个好的做法.我只是在试验.将小任务投入反应堆循环似乎是一件值得探讨的事情.如果我要进行一些非阻塞的http请求,为什么客户端必须等待?
虽然这个问题被标记为EventMachine,但任何语言的通用BSD套接字解决方案也非常受欢迎.
我有一个应用程序侦听TCP套接字.它使用常规的System V样式初始化脚本启动和关闭.
我的问题是它在准备好为TCP套接字服务之前需要一些时间来启动.它不会太长,也许只有5秒,但是在工作日需要重启时,这个时间太长了5秒.现有连接保持打开并正常完成也很重要.
重新启动应用程序的原因是补丁,升级等.不幸的是,我发现自己的位置,每隔一段时间,我就需要在生产中做这种事情.
我正在寻找一种方法来完成从一个进程到另一个进程的TCP侦听套接字的整齐移交,因此只能获得一秒钟的停机时间.我希望现有的连接/套接字保持打开状态并在旧进程中完成处理,而新进程开始为新连接提供服务.
是否有一些经过验证的方法使用BSD套接字执行此操作?(EventMachine解决方案的奖励积分.)
是否有可能实现这一点的开源库,我可以按原样使用,还是用作参考?(同样,非Ruby和非EventMachine解决方案也很受欢迎!)
我创建了一个Rails 3的异步版本,我想与WebSocket实现集成.
我正在使用EventMachine,Ruby 1.9,Fibers和各种em-flavored库,这些都是由邪恶的Ilya Grigorik记录的.
我一直在将em-websocket视为WebSocket连接的处理程序,但不确定将其连接到Rails应用程序的最佳方法.
理想情况下,这将与具有Express和Socket.io的node.js类似地工作 - 应检测传入连接并将其分派到WebSocket处理程序或常规rails堆栈,如HTTP标头等所示.
TL; DR
我正在使用Goliath(由eventmachine驱动)和postgres gem pg,目前我正以阻塞的方式使用pg gem :( conn.exec('SELECT * FROM products')例如)我想知道是否有更好的方式连接到postgres数据库?
我有一个应用程序,可以响应客户端发送的消息.一条消息是reload_credentials,应用程序会在新客户端注册时随时收到.然后,此消息将连接到PostgreSQL数据库,对所有凭据执行查询,然后将它们存储在常规Ruby哈希(client_id => client_token)中.
该应用程序可能会收到一些其他的消息是start,stop,pause这是用来跟踪一些会话倍.我的观点是,我设想应用程序以下列方式运行:
但是,例如,我不想阻止反应堆.此外,让我们想象一下,我的reload_credentials消息是下一个队列中的消息.在从数据库重新加载凭据之前,我不希望处理队列中的任何其他消息.此外,当我处理某个消息(如等待凭据查询完成)时,我想允许其他消息入队.
你能指导我解决这个问题吗?我想我可能要用em-synchrony,但我不确定.
我有一种情况,我想在Ruby中运行多个EventMachines - 有没有人有这方面的经验?(如果没有,我可以自己写一个测试用例.请继续关注).
让我们明确一点:我想自己实例化两个线程,并调用EventMachine.run两个线程,所以我真的有两个反应器循环.
原因是我正在使用AMQP gem编写异步消息总线,它使用EventMachine.这很好,但我想把它作为一个单独的模块化组件,可以在两个应用程序中使用:
有人有想法吗?
我在Ruby 1.9.2下运行此代码片段:
require "eventmachine"
require "fiber"
EM.run do
fiber = Fiber.new do
current_fiber = Fiber.current
EM.add_timer(2) do
print "B"
current_fiber.resume("D")
end
Fiber.yield
end
print "A"
val = fiber.resume
print "C"
print val
EM.stop
end
Run Code Online (Sandbox Code Playgroud)
我期待输出为"ABCD",程序在"A"后暂停两秒钟.但是,它只是立即打印出"AC",然后在退出前等待两秒钟.我究竟做错了什么?
(作为参考,我试图在不使用em-synchrony的情况下重现本文中描述的em-synchrony风格的行为.)
编辑:这里有一些关于我最终要完成的事情的更多细节.我正在开发一个在Thin上运行的Grape API,并且每个路由处理程序必须在返回响应之前对数据存储,ZooKeeper,其他HTTP服务等进行各种串行调用.
em-synchrony真的很酷,但是我一直遇到从根光纤屈服或结果显示上述情况的非同步症状的问题.rack-fiber_pool似乎也很有用,但我不愿意使用它,因为开箱即用它会破坏我所有的Rack :: Test单元测试.
我将问题简化为上面的简单示例,因为我似乎对如何一起使用光纤和EventMachine存在根本的误解,这阻碍了我有效地使用更复杂的框架.
关于Ruby的第一个问题.我正在尝试在Reactor循环中测试EventMachine交互 - 我猜它可以被归类为"功能"测试.
假设我有两个类 - 服务器和客户端.我想测试双方 - 我需要确定他们的互动.
服务器:
require 'singleton'
class EchoServer < EM::Connection
include EM::Protocols::LineProtocol
def post_init
puts "-- someone connected to the echo server!"
end
def receive_data data
send_data ">>>you sent: #{data}"
close_connection if data =~ /quit/i
end
def unbind
puts "-- someone disconnected from the echo server!"
end
end
Run Code Online (Sandbox Code Playgroud)
客户:
class EchoClient < EM::Connection
include EM::Protocols::LineProtocol
def post_init
send_data "Hello"
end
def receive_data(data)
@message = data
p data
end
def unbind
puts "-- someone disconnected from …Run Code Online (Sandbox Code Playgroud) eventmachine ×10
ruby ×8
asynchronous ×3
.net ×1
apple-m1 ×1
event-loop ×1
fibers ×1
goliath ×1
postgresql ×1
rack ×1
rspec ×1
rubygems ×1
sinatra ×1
sockets ×1
thin ×1
websocket ×1