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