16. Executor
• IOThreadPoolExecutor:
• IO intensive
• one event loop, notification queue(eventfd) per thread
• round robin, user define
• MPSC
• CPUThreadPoolExecutor:
• CPU intensive
• multi-threads single queue
• MPMC Queue, LIFO wakeup, cache efficiency
• ThreadedExecutor
• FiberIOExecutor(stackful)
• FutureExecutor
17. MPMC Queue
• LIFO Semaphore:
• approximately LIFO
• multi-post, exact wakeups, fewer system calls than sem_t
• MPMC Queue:
• fixed capacity, blocking or throw exception
• incremental ticket based, item index = hash(ticket)
• if holds item, wait for turn, else write the element
• a read ticket with same growing rule
• get the right version of element with ticket turn
• false sharing:
• advance by stride slots per ticket
• futex:
• Fast Userspace muTEXes, userspace (no competition), kernel space (wait, wakeup)
• tbb::concurrent_bounded_queue
19. Service
• Client Dispatcher:
• SerialClientDispatcher: one request is allowed at a time
• PipelinedClientDispatcher: use a promises queue for pipelining
• Server Dispatcher:
• SerialServerDispatcher: one at a time synchronously
• PipelinedServerDispatcher: queued with a request id until they can be sent in order
• MultiplexServerDispatcher: dispatch as they come in
• Common Filter:
• ExpiringFilter: expires the service after a certain amount of time
• ExecutorFilter: through an executor
20. Overload Protection
• CoDel:
• Controlled Delay
• an active queue management algorithm
• attacking bufferbloat
• if every request has experienced queuing delay greater than the target (5ms)
during the past interval (100ms), then shed load
• slough off requests which have exceeded an alternate timeout (2 * target_delay)
• back to normal if delay down to 5ms
• application case: RabbitMQ
25. EventBase
• based on libevent::event_base
• NotificationQueue:
• producer-consumer
• passing messages between EventBase threads
• use an eventfd
• loop():
• before loop callbacks
• event_base_loop
• loop callbacks, busy
• time measurement
• run NotificationQueue events
26. SmoothLoopTime
• dynamically adjusting loop time
• EMA Algorithm (Exponential Moving Average)
• https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
2
lastbusy busy
idle idle
+
= +
_int _int
1 (1 )
idle idle
time erval time erval
i iEMA EMA e e busy
− −
−= × + − ×
27. Acceptor
• Acceptor IO Executor
• multi-IP (SO_REUSEADDR), multi-thread accept (SO_REUSEPORT)
• bind, listen, accept4 (max accept at once)
• connection event callback
• adjusting connection accept rate
• put accept info into a NotificationQueue
• build connection info via Connection IO Executor
• active accept pipeline (Acceptor) read
• fire child pipeline
38. Futures
• f.via(e).then(a).then(b)
• via:
• set executor
• then:
• make a new future/promise pair
• set callback:
• function result will be set in the new promise
• return its future
39. Core
• shared state object for Future and Promise
• reference count: Future, Promise, Executor
• callback and result
• activated by Future Destructor
• Finite State Machine:
• Try:
• value and exception