Live data from Hacker News

"Ruby developers need to stop using EventMachine. It's the wrong direction."

slideshare.net

21–30 of 72 posts

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#21
post #13
post #9

Earlier quoted context omitted.

There are times when you might reach for select() not to scale the whole program, but because for instance you're trying to hot potato data from a Reader to a Writer. Obviously, the whole of Golang's concurrency model is lightweight threads scheduled on I/O events. But that's not exposed to the programmer; in fact, it's hermetically sealed away from the programmer from what I can tell. So now you know what I meant by…

every time you perform i/o, the current goroutine yields to the scheduler. If you want to manually yield to the scheduler, you call runtime.Gosched() and the calling goroutine yields. If you want to lock a goroutine into a specific thread, you call runtime.LockOSThread(). Everything is single-threaded to start until you call runtime.GOMAXPROCS(), but that's intended to go away in the very near future. So... I'm not s…

I'm referring to the system call. Sorry, I can see how that would cause lots of confusion.

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#22
post #9

Earlier quoted context omitted.

There are times when you might reach for select() not to scale the whole program, but because for instance you're trying to hot potato data from a Reader to a Writer. Obviously, the whole of Golang's concurrency model is lightweight threads scheduled on I/O events. But that's not exposed to the programmer; in fact, it's hermetically sealed away from the programmer from what I can tell. So now you know what I meant by…

Thanks. I think I understand a bit better now. Go provides concurrency primitives (scheduler yielding i/o, channels, goroutines, etc) upon which you can build your own "events". I agree (and this seems to be your point) that Go doesn't provide a canned event mechanism that you can just hook into for callbacks on IO. For example in the Go http server[1] a goroutine accepts in a loop and kicks off goroutines to process…

Sure, I'm using the Go http server.

Take the example of a simple proxy to see where I'm coming from. Sure, I'm happy to have Go manage all the connections and sockets and I'm happy to spawn new goroutines for each connection and all that. But a proxy accepts an inbound connection, makes an outbound connection, and then monitors the outbound and inbound sides for data. The loop to do this with sockets could be a simple two-descriptor read select(2) call. But instead, I have to spawn two more goroutines, one to "monitor" (really, read) from inbound, and one for outbound.

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#23
post #19
post #4

We write a lot of EventMachine code here; I have some questions. He writes: EventMachine is • A frankenstein guts the ruby internals • Not in active development • Makes non-blocking IO block • Requires special code from Ruby libraries • Hard to use in an OOP way • Is really difficult to work with • Poorly documented I'm not sure I understand how EventMachine "guts the Ruby internals" (I didn't watch the talk). It's tr…

> I'm not sure I understand how EventMachine "guts the Ruby internals" EventMachine does not use the Ruby IO primitives (e.g. TCPSocket, UDPSocket, etc) as the basis of its IO abstraction, and instead has reimplemented its own set of primitives for doing IO. Because of this it can't take advantage of work being done in Ruby core to advance Ruby's socket layer. For this reason IPv6 support langered, among other proble…

I like libevent and all, but I don't think Twisted's use of libevent is a particularly big win for Twisted.

Again, this is apocryphal, but I remember someone trying to wrap Ruby around libevent and failing; I remember there being a reason this had to be done bespoke. And having fallen into this particular NIH trap many times before: there's just not a whole lot to a simple socket I/O loop.

What's been your experience with JRuby/EventMachine?

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#24

If you really like evented programming, use node. Everything there is evented. I tried EventMachine and it just felt worse than node, documentation is worse, libraries are worse, it just wasn't a whole lot of fun. I haven't tried celluloid yet, but I've learned one lesson building things with PHP, Ruby, Python, Node, Java, Scala, etc. That lesson is to use tools with a community of people around it that are using tho…

Python programmers have been doing evented code for almost a decade using Twisted. EventMachine happened later, but then, so did the mainstreaming of Ruby. You realize, don't you, that Tcl has all three of Javascript, Ruby, and Python beat when it comes to evented I/O?

Node does not own evented I/O.

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#25
post #9

Earlier quoted context omitted.

> Golang is militantly anti-event; it doesn't even offer a select primitive! Just alternating read/write on two different sockets seems to demand threads! Go only blocks the goroutine. It uses native event primitives (epoll/kqueue/etc) under the hood so that IO is non-blocking to the rest of the process (e.g. other goroutines). You said you have used Go for 2 months, so I assume you are aware of that. So..can you be…

There are times when you might reach for select() not to scale the whole program, but because for instance you're trying to hot potato data from a Reader to a Writer. Obviously, the whole of Golang's concurrency model is lightweight threads scheduled on I/O events. But that's not exposed to the programmer; in fact, it's hermetically sealed away from the programmer from what I can tell. So now you know what I meant by…

Would you just select { case I know this isn't the same as posix select, but it does let you have one goroutine coordinate the hot potato..

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#26
post #4

We write a lot of EventMachine code here; I have some questions. He writes: EventMachine is • A frankenstein guts the ruby internals • Not in active development • Makes non-blocking IO block • Requires special code from Ruby libraries • Hard to use in an OOP way • Is really difficult to work with • Poorly documented I'm not sure I understand how EventMachine "guts the Ruby internals" (I didn't watch the talk). It's tr…

When I saw the title, I thought it was going to be coverage of how under-the-hood EventMachine's model only allows it to scale up to a certain throughput per-process (which is reasonably high for most uses of it) or how there is some fundamental complexity in how it's written that pretty much guarantees there will be livelock conditions (and deadlock conditions). So I share your bewilderment about why they chose the things to highlight that they did.

The lock conditions it has are for particular workloads at particular throughput/utilization, so 99% of the people using it won't hit those conditions initially (and a lot of people aren't writing systems that will ever reach those limits). However, we have a particular service that acts as a TCP multiplexer/router/load balancer to provide high availability for some of our mission critical applications. A little over a year ago, I initially wrote it using EventMachine in a couple of weeks, then spent almost a month trying to find what I thought was a bug in my code where a full deadlock would occur if 3 or more connections were established in a small enough time frame. Turned out to be a bug in EventMachine. After fixing that one, I found another where if 5 or more open connections fired the same event within a small enough time frame, all 5 would hit livelock and given enough connections hitting the condition, the whole process would deadlock. Once I hit the second bug in EventMachine itself directly related to concurrency handling, I switched to Netty and rewrote the whole thing in Scala in about a week and it's been rock solid since.

I've been doing some development on the side in Go because its particular flavor of types and concurrency model is fascinating. It's not that Go is anti-event, it's that it's overwhelmingly stream oriented (not low-level streams, but data streams). Once I finally hit that moment of clarity that goroutines/channels was all about connecting streams of data and not connecting raw streams, they became a much more natural solution. However, don't get me started on the difference between a non-blocking read on a channel and a blocking read on a channel.

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#27
post #22

Earlier quoted context omitted.

Thanks. I think I understand a bit better now. Go provides concurrency primitives (scheduler yielding i/o, channels, goroutines, etc) upon which you can build your own "events". I agree (and this seems to be your point) that Go doesn't provide a canned event mechanism that you can just hook into for callbacks on IO. For example in the Go http server[1] a goroutine accepts in a loop and kicks off goroutines to process…

Sure, I'm using the Go http server. Take the example of a simple proxy to see where I'm coming from. Sure, I'm happy to have Go manage all the connections and sockets and I'm happy to spawn new goroutines for each connection and all that. But a proxy accepts an inbound connection, makes an outbound connection, and then monitors the outbound and inbound sides for data. The loop to do this with sockets could be a simpl…

Is there a large overhead for having to use a goroutine rather than the lower level? Do you think it's appropriate for Go to expose that, or do you just miss it?

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#28
post #23
post #19

Earlier quoted context omitted.

> I'm not sure I understand how EventMachine "guts the Ruby internals" EventMachine does not use the Ruby IO primitives (e.g. TCPSocket, UDPSocket, etc) as the basis of its IO abstraction, and instead has reimplemented its own set of primitives for doing IO. Because of this it can't take advantage of work being done in Ruby core to advance Ruby's socket layer. For this reason IPv6 support langered, among other proble…

I like libevent and all, but I don't think Twisted's use of libevent is a particularly big win for Twisted. Again, this is apocryphal, but I remember someone trying to wrap Ruby around libevent and failing; I remember there being a reason this had to be done bespoke. And having fallen into this particular NIH trap many times before: there's just not a whole lot to a simple socket I/O loop. What's been your experience…

Zed shaw tried to make libevent work with Ruby, but this was when we had Ruby 1.8.5 and there were problems with Ruby interpreter that prevented this (around threading IIRC).

Re: "Ruby developers need to stop using EventMachine. It's the wrong direction."

#29
post #8
post #4

We write a lot of EventMachine code here; I have some questions. He writes: EventMachine is • A frankenstein guts the ruby internals • Not in active development • Makes non-blocking IO block • Requires special code from Ruby libraries • Hard to use in an OOP way • Is really difficult to work with • Poorly documented I'm not sure I understand how EventMachine "guts the Ruby internals" (I didn't watch the talk). It's tr…

> Golang is militantly anti-event; it doesn't even offer a select primitive s/anti-event/anti-callback/. They are not the same thing. Under the hood, Golang is doing the eventing and select() for you, while letting you write simple procedural code. > I try to force myself to write socket code like I did when I was 13, reading a line, parsing it, and writing its response, but that code is brittle and harder to follow…

> green threads (which look just like normal threaded code) as the best and simplest interface to the event-loop - as seen by Golang, gevent, Eventmachine, Coro (Perl) etc etc.

That list is just screaming for someone to write a comment mentioning that you forgot Erlang.

Post reply on HN