eventlet
eventlet coroutines — flexible efficient control flow greenlet non-blocking i/o — efficient network i/o select/poll/epoll threads — switch between async and sync queues/pipes
coroutines main subroutine: subroutine(1, 2) subroutine subroutine(3, 4) subroutine continue by returning to caller coroutine: main continue by calling coroutine.switch(1, 2) coroutine coroutine2.switch(3, 4) coroutine2 another coroutine main.switch('hello')
greenlet $ python coros.py 2 4 16 256 65536
non-blocking i/o blocking i/o: each “thread of control” can read or write on one file descriptor at a time process, thread non-blocking i/o: reads and writes are multiplexed using select, poll, epoll, kqueue, etc.
blocking i/o
non-blocking i/o
eventlet: coroutines + non-blocking i/o main loop (Hub) is responsible for calling i/o multiplexer function and scheduling timers eventlet.greenio provides a socket object which registers with the Hub and cooperatively switches instead of blocking code looks blocking, but all network i/o is non-blocking
eventlet.greenio socket.read(...) while not enough data: trampoline(socket, read=True) api.get_hub().add_descriptor( socket, read=api.get_current().switch) self.readers[socket] = callback api.get_hub().switch()
greenio part 2 ready_to_read, ready_to_write, exc = select(...) for read in ready_to_read: self.readers[read].switch() socket.recv(4096) once all requested data has been read, the socket.read(...) returns data
eventlet echo server
eventlet flowchart
integration with blocking code eventlet uses a cooperative single thread blocking code must cooperate eventlet provides cooperative: sockets pipes processes eventlet.tpool can mix blocking code with cooperative coroutines using a threadpool
threadpool details to call a function in a threadpool, eventlet puts the function, arguments, and current coroutine in a request queue threads in the pool block on the request queue the function is executed in the thread the result is put in the response queue a byte is written into a pipe which is being read by the main thread the result is sent to the original coroutine
naive threadpool
spawning
spawning http server wsgi server multiple network i/o processes multiple wsgi worker threads graceful code reloading
process model options single i/o process, multiple threads good for stateful applications multiple i/o process, single thread good for comet applications multiple i/o process, multiple thread good for the majority of applications
spawning controller main spawning controller process binds network socket i/o process forks network i/o processes multiple i/o processes can take advantage of multiple cpus
spawning child i/o processes use eventlet to scale to controller many keepalive sockets http protocol i/o process implementation in eventlet.wsgi wsgi thread dispatches to wsgi applications in threadpool
graceful reloading controller send controller sighup controller forks new processes with new code i/o process XXX existing processes stop accepting and complete i/o process outstanding requests, then exit
using spawning with paster serve: [server:main] use = egg:Spawning command line: spawn my_package.my_module.wsgi_app
spawn options spawn wsgi_app [wsgi_middleware, ...] --port=8080 --host=127.0.0.1 --processes=4 --threads=8 --threads=0 will use eventlet cooperation monkeypatching
Recommend
More recommend