48de55f3ab6055dc2dc2059e826ac8acfd09bc29
[folly.git] / folly / io / async / README.md
1 # folly/io/async: An object-oriented wrapper around libevent
2 ----------------------------------------------------------
3
4 [libevent](https://github.com/libevent/libevent) is an excellent
5 cross-platform eventing library.  Folly's async provides C++ object
6 wrappers for fd callbacks and event_base, as well as providing
7 implementations for many common types of fd uses.
8
9 ## EventBase
10
11 The main libevent / epoll loop.  Generally there is a single EventBase
12 per thread, and once started, nothing else happens on the thread
13 except fd callbacks.  For example:
14
15 ```
16 EventBase base;
17 auto thread = std::thread([&](){
18   base.loopForever();
19 });
20
21 ```
22
23 EventBase has built-in support for message passing between threads.
24 To send a function to be run in the EventBase thread, use
25 runInEventBaseThread().
26
27 ```
28 EventBase base;
29 auto thread1 = std::thread([&](){
30   base.loopForever();
31 });
32 base.runInEventBaseThread([&](){
33   printf("This will be printed in thread1\n");
34 });
35 ```
36
37 There are various ways to run the loop.  EventBase::loop() will return
38 when there are no more registered events.  EventBase::loopForever()
39 will loop until EventBase::terminateLoopSoon() is called.
40 EventBase::loopOnce() will only call epoll() a single time.
41
42 Other useful methods include EventBase::runAfterDelay() to run events
43 after some delay, and EventBase::setMaxLatency(latency, callback) to
44 run some callback if the loop is running very slowly, i.e., there are
45 too many events in this loop, and some code should probably be running
46 in different threads.
47
48 EventBase always calls all callbacks inline - that is, there is no
49 explicit or implicit queuing.  The specific implications of this are:
50
51 * Tail-latency times (P99) are vastly better than any queueing
52   implementation
53 * The EventHandler implementation is responsible for not taking too
54   long in any individual callback.  All of the EventHandlers in this
55   implementation already do a good job of this, but if you are
56   subclassing EventHandler directly, something to keep in mind.
57 * The callback cannot delete the EventBase or EventHandler directly,
58   since it is still on the call stack.  See DelayedDestruction class
59   description below, and use shared_ptrs appropriately.
60
61 ## EventHandler
62
63 EventHandler is the object wrapper for fd's.  Any class you wish to
64 receive callbacks on will inherit from
65 EventHandler. `registerHandler(EventType)` will register to receive
66 events of a specific type.
67
68 Currently supported event types:
69
70 * READ - read and EOF events
71 * WRITE - write events, when kernel write buffer is empty
72 * READ_WRITE - both
73 * PERSIST - The event will remain registered even after the handlerReady() fires
74
75 Unsupported libevent event types, and why-
76
77 * TIMEOUT - this library has specific timeout support, instead of
78   being attached to read/write fds.
79 * SIGNAL - similarly, signals are handled separately, see
80   AsyncSignalHandler
81 * EV_ET - Currently all the implementations of EventHandler are set up
82   for level triggered.  Benchmarking hasn't shown that edge triggered
83   provides much improvement.
84
85   Edge-triggered in this context means that libevent will provide only
86   a single callback when an event becomes active, as opposed to
87   level-triggered where as long as there is still data to read/write,
88   the event will continually fire each time event_wait is called.
89   Edge-triggered adds extra code complexity, since the library would
90   need to maintain a similar list of active FDs that libevent
91   currently does between edge triggering events.  The only advantage
92   of edge-triggered is that you can use EPOLLONESHOT to ensure the
93   event only gets called on a single event_base - but in this library,
94   we assume each event is only registered on a single thread anyway.
95
96 * EV_FINALIZE - EventBase can only be used in a single thread,
97   excepting a few methods.  To safely unregister an event from a
98   different thread, it would have to be done through
99   EventBase::runInEventBaseThread().  Most APIs already make this
100   thread transition for you, or at least CHECK() that you've done it
101   in the correct thread.
102 * EV_CLOSED - This is an optimization - instead of having to READ all
103   the data and then get an EOF, EV_CLOSED would fire before all the
104   data is read.  TODO: implement this.  Probably only useful in
105   request/response servers.
106
107 ## Implementations of EventHandler
108
109 ### AsyncSocket
110
111 A nonblocking socket implementation.  Writes are queued and written
112 asynchronously, even before connect() is successful.  The read api
113 consists of two methods: getReadBuffer() and readDataAvailable().
114 When the READ event is signaled, libevent has no way of knowing how
115 much data is available to read.   In some systems (linux), we *could*
116 make another syscall to get the data size in the kernel read buffer,
117 but syscalls are slow.  Instead, most users will just want to provide
118 a fixed size buffer in getReadBuffer(), probably using the IOBufQueue
119 in folly/io.   readDataAvailable() will then describe exactly how much
120 data was read.
121
122 AsyncSocket provides send timeouts, but not read timeouts - generally
123 read timeouts are application specific, and should use an AsyncTimer
124 implementation below.
125
126 Various notes:
127
128 * Using a chain of IOBuf objects, and calling writeChain(), is a very
129   syscall-efficient way to add/modify data to be sent, without
130   unnecessary copies.
131 * setMaxReadsPerEvent() - this prevents an AsyncSocket from blocking
132   the event loop for too long.
133 * Don't use the fd for syscalls yourself while it is being used in
134   AsyncSocket, instead use the provided wrappers, like
135   AsyncSocket::close(), shutdown(), etc.
136
137 #### AsyncSSLSocket
138
139 Similar to AsyncSocket, but uses openssl.  Provides an additional
140 HandshakeCallback to check the server's certificates.
141
142 #### TAsyncUDPSocket
143
144 TODO: Currently in fbthrift.
145
146 A socket that reads/writes UDP packets.  Since there is little state
147 to maintain, this is much simpler than AsyncSocket.
148
149 ### AsyncServerSocket
150
151 A listen()ing socket that accept()s fds, and passes them to other
152 event bases.
153
154 The general pattern is:
155
156 ```
157 EventBase base;
158 auto socket = AsyncServerSocket::newSocket(&base);
159 socket->bind(port); // 0 to choose any free port
160 socket->addAcceptCallback(object, &base); // where object is the object that implements the accept callback, and base is the object's eventbase.  base::runInEventBaseThread() will be called to send it a message.
161 socket->listen(backlog);
162 socket->startAccepting();
163 ```
164
165 Generally there is a single accept() thread, and multiple
166 AcceptCallback objects.  The Acceptee objects then will manage the
167 individual AsyncSockets.  While AsyncSockets *can* be moved between
168 event bases, most users just tie them to a single event base to get
169 better cache locallity, and to avoid locking.
170
171 Multiple ServerSockets can be made, but currently the linux kernel has
172 a lock on accept()ing from a port, preventing more than ~20k accepts /
173 sec.  There are various workarounds (SO_REUSEPORT), but generally
174 clients should be using connection pooling instead when possible.
175
176 Since AsyncServerSocket provides an fd, an AsyncSSLSocket or
177 AsyncSocket can be made using the same codepath
178
179 #### TAsyncUDPServerSocket
180
181 Similar to AsyncServerSocket, but for UDP messages - messages are
182 read() on a single thread, and then fanned out to multiple worker
183 threads.
184
185 ### NotificationQueue (EventFD or pipe notifications)
186
187 NotificationQueue is used to send messages between threads in the
188 *same process*.  It is what backs EventBase::runInEventBaseThread(),
189 so it is unlikely you'd want to use it directly instead of using
190 runInEventBaseThread().
191
192 An eventFD (for kernels > 2.6.30) or pipe (older kernels) are added to
193 the EventBase loop to wake up threads receiving messages.   The queue
194 itself is a spinlock-guarded list.   Since we are almost always
195 talking about a single sender thread and a single receiver (although
196 the code works just fine for multiple producers and multiple
197 consumers), the spinlock is almost always uncontended, and we haven't
198 seen any perf issues with it in practice.
199
200 The eventfd or pipe is only notified if the thread isn't already
201 awake, to avoid syscalls.  A naive implementaiton that does one write
202 per message in the queue, or worse, writes the whole message to the
203 queue, would be significantly slower.
204
205 If you need to send messages *between processes*, you would have to
206 write the whole message to the pipe, and manage the pipe size.  See
207 AsyncPipe.
208
209 ### AsyncTimeout
210
211 An individual timeout callback that can be installed in the event
212 loop.   For code cleanliness and clarity, timeouts are separated from
213 sockets.   There is one fd used per AsyncTimeout.  This is a pretty
214 serious restriction, so the two below subclasses were made to support
215 multiple timeouts using a single fd.
216
217 #### HHWheelTimer
218
219 Implementation of a [hashed hierarchical wheel
220 timer](http://www.cs.columbia.edu/~nahum/w6998/papers/sosp87-timing-wheels.pdf).
221 Any timeout time can be used, with O(1) insertion, deletion, and
222 callback time.  The wheel itself takes up some amount of space, and
223 wheel timers have to have a constant tick, consuming a constant amount
224 of CPU.
225
226 An alternative to a wheel timer would be a heap of callbacks sorted by
227 timeout time, but would change the big-O to O(log n).  In our
228 experience, the average server has thousands to hundreds of thousands
229 of open sockets, and the common case is to add and remove timeouts
230 without them ever firing, assuming the server is able to keep up with
231 the load.  Therefore O(log n) insertion time overshadows the extra CPU
232 consumed by a wheel timer tick.
233
234 #### TAsyncTimeoutSet
235
236 NOTE: currently in proxygen codebase.
237
238 If we assume that all timeouts scheduled use the same timeout time, we
239 can keep O(1) insertion time: just schedule the new timeout at the
240 tail of the list, along with the time it was actually added.  When the
241 current timeout fires, we look at the new head of the list, and
242 schedule AsyncTimeout to fire at the difference between the current
243 time and the scheduled time (which probably isn't the same as the
244 timeout time.)
245
246 This requires all AsyncTimeoutSets timeouts to have the same timeout
247 time though, which in practice means many AsyncTimeoutSets are needed
248 per application.   Using HHWheelTimer instead can clean up the code quite
249 a bit, because only a single HHWheelTimer is needed per thread, as
250 opposed to one AsyncTimeoutSet per timeout time per thread.
251
252 ### AsyncSignalHandler
253
254 Used to handle AsyncSignals.  Similar to AsyncTimeout, for code
255 clarity, we don't reuse the same fd as a socket to receive signals.
256
257 ### AsyncPipe
258
259 Async reads/writes to a unix pipe, to send data between processes.
260
261 ## Helper Classes
262
263 ### RequestContext (in Request.h)
264
265 Since messages are frequently passed between threads with
266 runInEventBaseThread(), ThreadLocals don't work for messages.
267 Instead, RequestContext can be used, which is saved/restored between
268 threads.  Major uses for this include:
269
270 * NUMA: saving the numa node the code was running on, and explicitly
271   running it on the same node in other threadpools / eventbases
272 * Tracing: tracing requests dapper-style intra machine, as well as
273   between threads themselves.
274
275 In this library only runInEventBaseThread save/restores the request
276 context, although other Facebook libraries that pass requests between
277 threads do also: folly::future, and fbthrift::ThreadManager, etc
278
279 ### DelayedDestruction
280
281 Since EventBase callbacks already have the EventHandler and EventBase
282 on the stack, calling `delete` on either of these objects would most
283 likely result in a segfault.  Instead, these objects inherit from
284 DelayedDestruction, which provides reference counting in the
285 callbacks.  Instead of delete, `destroy()` is called, which notifies
286 that is ready to be destroyed.  In each of the callbacks there is a
287 DestructorGuard, which prevents destruction until all the Guards are
288 gone from the stack, when the actual delete method is called.
289
290 DelayedDestruction can be a painful to use, since shared_ptrs and
291 unique_ptrs need to have a special DelayedDestruction destructor
292 type.  It's also pretty easy to forget to add a DestructorGuard in
293 code that calls callbacks.  But it is well worth it to avoid queuing
294 callbacks, and the improved P99 times as a result.
295
296 ### DestructorCheck
297
298 Often for an object requesting callbacks from other components (timer,
299 socket connect, etc.) there is a chance that the requestor will be
300 deallocated before it'll receive the callback.  One of the ways to avoid
301 dereferencing the deallocated object from callbacks is to derive the
302 object from DelayedDestruction, and add a delayed destruction guard
303 to the callback context.  In case if keeping the object around until
304 all the requested callbacks fire is too expensive, or if the callback
305 requestor can't have private destructor (it's allocated on the stack,
306 or as a member of a larger object), DestructorCheck can be used.
307 DestructorCheck is not affecting object life time. It helps other
308 component to detect safely that the tracked object was deallocated.
309
310 The object requesting the callback must be derived from DestructorCheck.
311 The callback context should contain an instance of
312 DestructorCheck::Safety object initialized with a reference to the
313 object requesting the callback.  Safety object can be captured by value
314 in the callback lambda, or explicitly added to a predefined callback
315 context class. Multiple instances of Safety object can be instantiated
316 for the same tracked object.  Once the callback is invoked, before
317 dereferencing the requester object, callback code should make sure that
318 `destroyed()` method for the corresponding Safety object returns false.
319
320 ### EventBaseManager
321
322 DANGEROUS.
323
324 Since there is ususally only a single EventBase per thread, why not
325 make EventBase managed by a threadlocal?  Sounds easy!  But there are
326 several catches:
327
328 * The EventBase returned by `EventBaseManager::get()->getEventBase()`
329   may not actually be running.
330 * There may be more than one event base in the thread (unusual), or
331   the EventBase in the code may not be registerd in EventBaseManager.
332 * The event bases in EventBaseManager may be used for different
333   purposes, i.e. some are AsyncSocket threads, and some are
334   AsyncServerSocket threads:  So you can't just grab the list of
335   EventBases and call runInEventBaseThread() on all of them and expect
336   it to do the right thing.
337
338 A much safer option is to explicitly pass around an EventBase, or use
339 an explicit pool of EventBases.
340
341 ### SSLContext
342
343 SSL helper routines to load / verify certs.  Used with
344 AsyncSSLSocket.
345
346 ## Generic Multithreading Advice
347
348 Facebook has a lot of experience running services.  For background
349 reading, see [The C10k problem](http://www.kegel.com/c10k.html) and
350 [Fast UNIX
351 servers](http://nick-black.com/dankwiki/index.php/Fast_UNIX_Servers)
352
353 Some best practices we've found:
354
355 1. It's much easier to maintain latency expectations when each
356    EventBase thread is used for only a single purpose:
357    AsyncServerSocket, or inbound AsyncSocket, or in proxies, outbound
358    AsyncSocket calls.   In a perfect world, one EventBase per thread
359    per core would be enough, but the implementor needs to be extremely
360    diligent to make sure all CPU work is moved off of the IO threads to
361    prevent slow read/write/closes of fds.
362 2. **ANY** work that is CPU intensive should be offloaded to a pool of
363    CPU-bound threads, instead of being done in the EventBase threads.
364    runInEventBaseThread() is fast:  It can be called millions of times
365    per second before the spinlock becomes an issue - so passing the
366    request off to a different thread is probably fine perf wise.
367 3. In contrast to the first two recommendations, if there are more
368    total threads than cores, context switching overhead can become an
369    issue.  In particular we have seen this be an issue when a
370    CPU-intensive thread blocks the scheduling of an IO thread, using
371    the linux `perf sched` tool.
372 4. For async programming, in contrast to synchronous systems, managing
373    load is extremely hard - it is better to use out-of-band methods to
374    notify of overload, such as timeouts, or CPU usage.  For sync
375    systems, you are almost always limited by the number of threads.
376    For more details see [No Time for
377    Asynchrony](https://www.usenix.org/legacy/event/hotos09/tech/full_papers/aguilera/aguilera.pdf)