samuel / oriontransfer.net wrote:
> I hacked in EPOLLONESHOT semantics into my runloop. IT was
> about the same performance. But when I leveraged it correctly
> (calling `EPOLL_CTL_ADD` when accepting IO once, and
> `EPOLL_CTL_DEL` when closing IO, then `EPOLL_CTL_MOD` when
> waiting for event), I saw a 25% improvement in throughput. It
> was just a very rough test case but interesting none the less.

I would not expect one-shot to improve things unless you design
your application around it.  It also won't help if you only
expect to deal with well-behaved clients and your application
processing times are uniform.

One-shot helps with application design and allows in resource
migration when sharing the queue across threads.  Again, this
design may harm overall throughput and performance under IDEAL
conditions.  That's because there is a single queue and assumes
all requests can be processed at roughly the same speed.

However in NON-IDEAL conditions, some endpoints are handled more
slowly than others.  They are slow because the application needs
to do more work, like an expensive calculation or FS access,
NOT because of a "slow client".


One-shot also makes application design easier when an evil
client which is aggressively pipelining requests to request
large responses, yet reading slowly.  Thus, the evil client is
fast at writing requests, but slow at reading responses.

Server and reactor designers sometimes don't consider this case:
I haven't checked in years, but EventMachine was a huge offender
here since it didn't allow disabling read callbacks at all.
What happened was evil clients could keep sending requests,
and the server would keep processing them and writing responses
to a userspace buffer which the evil client was never draining.
So, eventually, it would trigger OOM on the server.


Non-oneshot reactor designs need to consider this attack vector.
One-shot designs don't even need to think about it, because it's
not "reacting" with callbacks.  One-shot uses EPOLL_CTL_MOD (or
EV_ADD) only when the reader/writer hits EAGAIN.  With one-shot
you won't have to deal with disabling callbacks which blindly
"react" to whatever evil clients send you.

So in my experience, one-shot saves me a lot of time since I
don't have to keep track of as much state in userspace and
remember to disable callbacks from firing if an evil client is
sending requests faster than they're reading them.

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>