Distributed Systems with ZeroMQ and gevent                 Jeff Lindsay                 @progrium
Why distributed systems? Harness more CPUs and resources Run faster in parallel Tolerance of individual failures Better se...
Most web apps evolve into  distributed systems
OpenStack
Amazon AWS                        ProviderWeb                           Provider APIClient                         Provide...
ZeroMQ + geventTwo powerful and misunderstood tools
ConcurrencyHeart of Distributed Systems
Distributed computingis just another flavor of    local concurrency
Multithreading         Shared MemoryThread       Thread        Thread  Distributed system         Shared Database App     ...
Concurrency modelsExecution model Defines the “computational unit”Communication model Means of sharing and coordination
Concurrency modelsTraditional multithreading  OS threads  Shared memory, locks, etcAsync or Evented I/O  I/O loop + callba...
ExamplesErlang  Actor modelScala  Actor modelGo  Channels, GoroutinesEverything else (Ruby, Python, PHP, Perl, C/C++, Java...
Erlang is special.     Normally, the networking ofdistributed systems is tacked on to the       local concurrency model.  ...
Why not always use Erlang?
Why not always use Erlang?Half reasons Weird/ugly language Limited library ecosystem VM requires operational expertise Fun...
Why not always use Erlang?Half reasons  Weird/ugly language  Limited library ecosystem  VM requires operational expertise ...
Amazon AWS                        ProviderWeb                           Provider APIClient                         Provide...
Service Oriented  Architecture    Multiple languages   Heterogeneous cluster
RPC
RPCClient / server
RPCClient / serverMapping to functions
RPCClient / serverMapping to functionsMessage serialization
RPC       Client / server       Mapping to functions       Message serializationPoor abstraction of what you really want
What you want are tools to help you get distributedactor model concurrency like Erlang ... without Erlang.     Even better...
Rarely will you build an application aspart of a distributed system that does   not also need local concurrency.
Communication modelHow do we unify communications in local concurrency     and distributed systems across languages?
Execution modelHow do we get Erlang-style local concurrency without interfering with the languages idiomatic paradigm?
ZeroMQCommunication model
Misconceptions
MisconceptionsIt’s just another MQ, right?
MisconceptionsIt’s just another MQ, right?   Not really.
MisconceptionsIt’s just another MQ, right?   Not really.
MisconceptionsIt’s just another MQ, right?   Not really.Oh, it’s just sockets, right?
MisconceptionsIt’s just another MQ, right?   Not really.Oh, it’s just sockets, right? Not really.
MisconceptionsIt’s just another MQ, right?   Not really.Oh, it’s just sockets, right? Not really.
MisconceptionsIt’s just another MQ, right?   Not really.Oh, it’s just sockets, right? Not really.Wait, isn’t messaging a s...
MisconceptionsIt’s just another MQ, right?   Not really.Oh, it’s just sockets, right? Not really.Wait, isn’t messaging a s...
Regular Sockets
Regular SocketsPoint to point
Regular SocketsPoint to pointStream of bytes
Regular SocketsPoint to pointStream of bytesBuffering
Regular SocketsPoint to pointStream of bytesBufferingStandard API
Regular SocketsPoint to pointStream of bytesBufferingStandard APITCP/IP or UDP, IPC
Messaging
MessagingMessages are atomic
MessagingMessages are atomic
MessagingMessages are atomic
MessagingMessages are atomic
MessagingMessages are atomic   Messages can be routed
MessagingMessages are atomic   Messages can be routed
MessagingMessages are atomic   Messages can be routed
Messaging Messages are atomic      Messages can be routedMessages may sit around
Messaging Messages are atomic      Messages can be routedMessages may sit around
Messaging Messages are atomic      Messages can be routedMessages may sit around
Messaging Messages are atomic      Messages can be routedMessages may sit around
Messaging Messages are atomic      Messages can be routedMessages may sit around
Messaging Messages are atomic      Messages can be routedMessages may sit around
Messaging Messages are atomic      Messages can be routedMessages may sit around   Messages are delivered
Messaging Messages are atomic      Messages can be routedMessages may sit around   Messages are delivered
Rise of the Big MQ
App      App               Reliable            Message Broker               Persistent                 Queues             ...
App      App                  AppApp
AMQP            MQProducer                  Consumer
AMQP                           MQ                      BindingProducer      X                                        Consu...
AMQP                       MQProducer      X                                    Consumer           Exchange         Queue
AMQP Recipes
AMQP RecipesWork queuesDistributing tasks among workers
AMQP RecipesWork queues                        Publish/SubscribeDistributing tasks among workers   Sending to many consume...
AMQP RecipesWork queues                        Publish/SubscribeDistributing tasks among workers   Sending to many consume...
AMQP RecipesWork queues                        Publish/SubscribeDistributing tasks among workers   Sending to many consume...
Drawbacks of Big MQ   Lots of complexity   Queues are heavyweight   HA is a challenge   Poor primitives
Enter ZeroMQ“Float like a butterfly, sting like a bee”
Echo in Python                Server                                     Client1   import zmq                             ...
Echo in Ruby                 Server                                     Client 1   require "zmq"                          ...
Echo in PHP                     Server                                               Client 1   <?php                     ...
Bindings ActionScript, Ada, Bash, Basic, C, Chicken Scheme, Common Lisp, C#, C++, D, Erlang,F#, Go, Guile, Haskell, Haxe, ...
Plumbing
Plumbing
Plumbing
Plumbing
Plumbing
Plumbinginprocipctcpmulticast
Plumbinginprocipctcpmulticast  socket.bind("tcp://localhost:5560")  socket.bind("ipc:///tmp/this-socket")  socket.connect(...
Plumbinginprocipctcpmulticast  socket.bind("tcp://localhost:5560")  socket.bind("ipc:///tmp/this-socket")  socket.connect(...
Plumbinginprocipctcpmulticast  socket.bind("tcp://localhost:5560")  socket.bind("ipc:///tmp/this-socket")  socket.connect(...
Message Patterns
Message PatternsRequest-ReplyREQ      REP
Message PatternsRequest-Reply       REPREQ          REP       REP
Message PatternsRequest-Reply       REPREQ          REP       REP
Message PatternsRequest-Reply       REPREQ          REP       REP
Message PatternsRequest-Reply       REPREQ          REP       REP
Message PatternsRequest-Reply      Publish-Subscribe       REP                  SUBREQ          REP     PUB          SUB  ...
Message Patterns   Request-Reply           Publish-Subscribe            REP                     SUB    REQ           REP  ...
Message Patterns   Request-Reply           Publish-Subscribe            REP                     SUB    REQ           REP  ...
Message Patterns   Request-Reply           Publish-Subscribe            REP                     SUB    REQ           REP  ...
Message Patterns   Request-Reply           Publish-Subscribe            REP                     SUB    REQ           REP  ...
Message Patterns   Request-Reply           Publish-Subscribe            REP                        SUB    REQ           RE...
DevicesQueue         Forwarder            Streamer   Design architectures around devices.
DevicesQueue          Forwarder           Streamer         REQ                 REP   Design architectures around devices.
DevicesQueue          Forwarder           Streamer         PUB                 SUB   Design architectures around devices.
DevicesQueue           Forwarder           Streamer         PUSH                PULL   Design architectures around devices.
Performance
PerformanceOrders of magnitude faster than most MQs
PerformanceOrders of magnitude faster than most MQsHigher throughput than raw sockets
PerformanceOrders of magnitude faster than most MQsHigher throughput than raw sockets Intelligent message batching
PerformanceOrders of magnitude faster than most MQsHigher throughput than raw sockets Intelligent message batching Edge ca...
Concurrency?"Come for the messaging, stay for the easy concurrency"
Hintjens’ Law of Concurrency            e=      mc 2    E is effort, the pain that it takes    M is mass, the size of the c...
Hintjens’ Law of Concurrency
Hintjens’ Law of Concurrency
Hintjens’ Law of Concurrency         ZeroMQ:   e=mc 2,   for c=1
ZeroMQ    Easy       ... familiar socket API    Cheap      ... lightweight queues in a library    Fast       ... higher th...
geventExecution model
Threading vs EventedEvented seems to be preferred for scalable I/O applications
Evented Stack  Non-blocking Code    Flow Control   I/O Abstraction      Reactor                       I/O                 ...
1   def lookup(country, search_term): 2       main_d = defer.Deferred() 3 4       def first_step(): 5           query = "h...
gevent     “Regular” PythonGreenlets       Monkey patching   Reactor / Event Poller
Green threads“Threads” implemented in user space (VM, library)
Monkey patching  socket, ssl, threading, time
Twisted
Twisted~400 modules
gevent25 modules
Performance              http://nichol.as
Performance              http://nichol.as
Performance              http://nichol.as
Building a Networking App 1   #=== 2   # 1. Basic gevent TCP server 3 4   from gevent.server import StreamServer 5 6   def...
1   #=== 2   # 2. Basic gevent TCP server and WSGI server 3 4   from gevent.pywsgi import WSGIServer 5   from gevent.serve...
1   from gevent.pywsgi import WSGIServer 2   from gevent.server import StreamServer 3   from gevent.socket import create_c...
1   from gevent.pywsgi import WSGIServer 2   from gevent.server import StreamServer 3   from gevent.socket import create_c...
ZeroMQ in gevent?
1   from gevent import spawn 2   from gevent_zeromq import zmq 3 4   context = zmq.Context() 5 6   def serve(): 7       so...
Actor model?Easy to implement, in whole or in part,       optionally with ZeroMQ
What is gevent missing?
What is gevent missing?    Documentation
What is gevent missing?    Documentation    Application framework
gserviceApplication framework for gevent
1   from gevent.pywsgi import WSGIServer 2   from gevent.server import StreamServer 3   from gevent.socket import create_c...
1   from gevent.pywsgi import WSGIServer 2   from gevent.server import StreamServer 3   from gevent.socket import create_c...
1   from gservice.core import Service 2   from gservice.config import Setting 3 4   class MyApplication(Service): 5       ...
1   # example.conf.py 2 3   pidfile = example.pid 4   logfile = example.log 5   http_port = 8080 6   tcp_port = 1234 7   c...
Generalizinggevent proves a model that can be implemented in almost   any language that can implement an evented stack
gevent Easy       ... just normal Python Small      ... only 25 modules Fast       ... top performing server Compatible .....
Raiden Lightning fast, scalable messaginghttps://github.com/progrium/raiden
Concurrency modelsTraditional multithreadingAsync or Evented I/OActor model
ConclusionTwo very simple, but very powerful tools  for distributed / concurrent systems
Thanks @progrium
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Lindsay distributed geventzmq
Upcoming SlideShare
Loading in...5
×

Lindsay distributed geventzmq

2,687

Published on

Published in: Technology
0 Comments
15 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,687
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
15
Embeds 0
No embeds

No notes for slide

Lindsay distributed geventzmq

  1. 1. Distributed Systems with ZeroMQ and gevent Jeff Lindsay @progrium
  2. 2. Why distributed systems? Harness more CPUs and resources Run faster in parallel Tolerance of individual failures Better separation of concerns
  3. 3. Most web apps evolve into distributed systems
  4. 4. OpenStack
  5. 5. Amazon AWS ProviderWeb Provider APIClient Provider TwiML
  6. 6. ZeroMQ + geventTwo powerful and misunderstood tools
  7. 7. ConcurrencyHeart of Distributed Systems
  8. 8. Distributed computingis just another flavor of local concurrency
  9. 9. Multithreading Shared MemoryThread Thread Thread Distributed system Shared Database App App App
  10. 10. Concurrency modelsExecution model Defines the “computational unit”Communication model Means of sharing and coordination
  11. 11. Concurrency modelsTraditional multithreading OS threads Shared memory, locks, etcAsync or Evented I/O I/O loop + callback chains Shared memory, futuresActor model Shared nothing “processes” Built-in messaging
  12. 12. ExamplesErlang Actor modelScala Actor modelGo Channels, GoroutinesEverything else (Ruby, Python, PHP, Perl, C/C++, Java) Threading Evented
  13. 13. Erlang is special. Normally, the networking ofdistributed systems is tacked on to the local concurrency model. MQ, RPC, REST, ...
  14. 14. Why not always use Erlang?
  15. 15. Why not always use Erlang?Half reasons Weird/ugly language Limited library ecosystem VM requires operational expertise Functional programming isn’t mainstream
  16. 16. Why not always use Erlang?Half reasons Weird/ugly language Limited library ecosystem VM requires operational expertise Functional programming isn’t mainstreamBiggest reason It’s not always the right tool for the job
  17. 17. Amazon AWS ProviderWeb Provider APIClient Provider TwiML
  18. 18. Service Oriented Architecture Multiple languages Heterogeneous cluster
  19. 19. RPC
  20. 20. RPCClient / server
  21. 21. RPCClient / serverMapping to functions
  22. 22. RPCClient / serverMapping to functionsMessage serialization
  23. 23. RPC Client / server Mapping to functions Message serializationPoor abstraction of what you really want
  24. 24. What you want are tools to help you get distributedactor model concurrency like Erlang ... without Erlang. Even better if theyre decoupled and optional.
  25. 25. Rarely will you build an application aspart of a distributed system that does not also need local concurrency.
  26. 26. Communication modelHow do we unify communications in local concurrency and distributed systems across languages?
  27. 27. Execution modelHow do we get Erlang-style local concurrency without interfering with the languages idiomatic paradigm?
  28. 28. ZeroMQCommunication model
  29. 29. Misconceptions
  30. 30. MisconceptionsIt’s just another MQ, right?
  31. 31. MisconceptionsIt’s just another MQ, right? Not really.
  32. 32. MisconceptionsIt’s just another MQ, right? Not really.
  33. 33. MisconceptionsIt’s just another MQ, right? Not really.Oh, it’s just sockets, right?
  34. 34. MisconceptionsIt’s just another MQ, right? Not really.Oh, it’s just sockets, right? Not really.
  35. 35. MisconceptionsIt’s just another MQ, right? Not really.Oh, it’s just sockets, right? Not really.
  36. 36. MisconceptionsIt’s just another MQ, right? Not really.Oh, it’s just sockets, right? Not really.Wait, isn’t messaging a solved problem?
  37. 37. MisconceptionsIt’s just another MQ, right? Not really.Oh, it’s just sockets, right? Not really.Wait, isn’t messaging a solved problem? *sigh* ... maybe.
  38. 38. Regular Sockets
  39. 39. Regular SocketsPoint to point
  40. 40. Regular SocketsPoint to pointStream of bytes
  41. 41. Regular SocketsPoint to pointStream of bytesBuffering
  42. 42. Regular SocketsPoint to pointStream of bytesBufferingStandard API
  43. 43. Regular SocketsPoint to pointStream of bytesBufferingStandard APITCP/IP or UDP, IPC
  44. 44. Messaging
  45. 45. MessagingMessages are atomic
  46. 46. MessagingMessages are atomic
  47. 47. MessagingMessages are atomic
  48. 48. MessagingMessages are atomic
  49. 49. MessagingMessages are atomic Messages can be routed
  50. 50. MessagingMessages are atomic Messages can be routed
  51. 51. MessagingMessages are atomic Messages can be routed
  52. 52. Messaging Messages are atomic Messages can be routedMessages may sit around
  53. 53. Messaging Messages are atomic Messages can be routedMessages may sit around
  54. 54. Messaging Messages are atomic Messages can be routedMessages may sit around
  55. 55. Messaging Messages are atomic Messages can be routedMessages may sit around
  56. 56. Messaging Messages are atomic Messages can be routedMessages may sit around
  57. 57. Messaging Messages are atomic Messages can be routedMessages may sit around
  58. 58. Messaging Messages are atomic Messages can be routedMessages may sit around Messages are delivered
  59. 59. Messaging Messages are atomic Messages can be routedMessages may sit around Messages are delivered
  60. 60. Rise of the Big MQ
  61. 61. App App Reliable Message Broker Persistent Queues AppApp
  62. 62. App App AppApp
  63. 63. AMQP MQProducer Consumer
  64. 64. AMQP MQ BindingProducer X Consumer Exchange Queue
  65. 65. AMQP MQProducer X Consumer Exchange Queue
  66. 66. AMQP Recipes
  67. 67. AMQP RecipesWork queuesDistributing tasks among workers
  68. 68. AMQP RecipesWork queues Publish/SubscribeDistributing tasks among workers Sending to many consumers at once X
  69. 69. AMQP RecipesWork queues Publish/SubscribeDistributing tasks among workers Sending to many consumers at once XRoutingReceiving messages selectively foo X bar baz
  70. 70. AMQP RecipesWork queues Publish/SubscribeDistributing tasks among workers Sending to many consumers at once XRouting RPCReceiving messages selectively Remote procedure call implementation foo X bar baz
  71. 71. Drawbacks of Big MQ Lots of complexity Queues are heavyweight HA is a challenge Poor primitives
  72. 72. Enter ZeroMQ“Float like a butterfly, sting like a bee”
  73. 73. Echo in Python Server Client1 import zmq 1 import zmq2 context = zmq.Context() 2 context = zmq.Context()3 socket = context.socket(zmq.REP) 3 socket = context.socket(zmq.REQ)4 socket.bind("tcp://127.0.0.1:5000") 4 socket.connect("tcp://127.0.0.1:5000")5 56 while True: 6 for i in range(10):7 msg = socket.recv() 7 msg = "msg %s" % i8 print "Received", msg 8 socket.send(msg)9 socket.send(msg) 9 print "Sending", msg 10 reply = socket.recv()
  74. 74. Echo in Ruby Server Client 1 require "zmq" 1 require "zmq" 2 context = ZMQ::Context.new(1) 2 context = ZMQ::Context.new(1) 3 socket = context.socket(ZMQ::REP) 3 socket = context.socket(ZMQ::REQ) 4 socket.bind("tcp://127.0.0.1:5000") 4 socket.connect("tcp://127.0.0.1:5000") 5 5 6 loop do 6 (0...10).each do |i| 7 msg = socket.recv 7 msg = "msg #{i}" 8 puts "Received #{msg}" 8 socket.send(msg) 9 socket.send(msg) 9 puts "Sending #{msg}"10 end 10 reply = socket.recv 11 end
  75. 75. Echo in PHP Server Client 1 <?php 1 <?php 2 $context = new ZMQContext(); 2 $context = new ZMQContext(); 3 $socket = $context->getSocket(ZMQ::SOCKET_REP); 3 $socket = $context->getSocket(ZMQ::SOCKET_REQ); 4 $socket->bind("tcp://127.0.0.1:5000"); 4 $socket->connect("tcp://127.0.0.1:5000"); 5 5 6 while (true) { 6 foreach (range(0, 9) as $i) { 7 $msg = $socket->recv(); 7 $msg = "msg {$i}"; 8 echo "Received {$msg}"; 8 $socket->send($msg); 9 $socket->send($msg); 9 echo "Sending {$msg}";10 } 10 $reply = $socket->recv();11 ?> 11 } 12 ?>
  76. 76. Bindings ActionScript, Ada, Bash, Basic, C, Chicken Scheme, Common Lisp, C#, C++, D, Erlang,F#, Go, Guile, Haskell, Haxe, Java, JavaScript, Lua, Node.js, Objective-C, Objective Caml, ooc, Perl, PHP, Python, Racket, REBOL, Red, Ruby, Smalltalk
  77. 77. Plumbing
  78. 78. Plumbing
  79. 79. Plumbing
  80. 80. Plumbing
  81. 81. Plumbing
  82. 82. Plumbinginprocipctcpmulticast
  83. 83. Plumbinginprocipctcpmulticast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  84. 84. Plumbinginprocipctcpmulticast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  85. 85. Plumbinginprocipctcpmulticast socket.bind("tcp://localhost:5560") socket.bind("ipc:///tmp/this-socket") socket.connect("tcp://10.0.0.100:9000") socket.connect("ipc:///tmp/another-socket") socket.connect("inproc://another-socket")
  86. 86. Message Patterns
  87. 87. Message PatternsRequest-ReplyREQ REP
  88. 88. Message PatternsRequest-Reply REPREQ REP REP
  89. 89. Message PatternsRequest-Reply REPREQ REP REP
  90. 90. Message PatternsRequest-Reply REPREQ REP REP
  91. 91. Message PatternsRequest-Reply REPREQ REP REP
  92. 92. Message PatternsRequest-Reply Publish-Subscribe REP SUBREQ REP PUB SUB REP SUB
  93. 93. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUBPush-Pull (Pipelining) PULL PUSH PULL PULL
  94. 94. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUBPush-Pull (Pipelining) PULL PUSH PULL PULL
  95. 95. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUBPush-Pull (Pipelining) PULL PUSH PULL PULL
  96. 96. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUBPush-Pull (Pipelining) PULL PUSH PULL PULL
  97. 97. Message Patterns Request-Reply Publish-Subscribe REP SUB REQ REP PUB SUB REP SUBPush-Pull (Pipelining) Pair PULL PULL PAIR PAIR PUSH PULL
  98. 98. DevicesQueue Forwarder Streamer Design architectures around devices.
  99. 99. DevicesQueue Forwarder Streamer REQ REP Design architectures around devices.
  100. 100. DevicesQueue Forwarder Streamer PUB SUB Design architectures around devices.
  101. 101. DevicesQueue Forwarder Streamer PUSH PULL Design architectures around devices.
  102. 102. Performance
  103. 103. PerformanceOrders of magnitude faster than most MQs
  104. 104. PerformanceOrders of magnitude faster than most MQsHigher throughput than raw sockets
  105. 105. PerformanceOrders of magnitude faster than most MQsHigher throughput than raw sockets Intelligent message batching
  106. 106. PerformanceOrders of magnitude faster than most MQsHigher throughput than raw sockets Intelligent message batching Edge case optimizations
  107. 107. Concurrency?"Come for the messaging, stay for the easy concurrency"
  108. 108. Hintjens’ Law of Concurrency e= mc 2 E is effort, the pain that it takes M is mass, the size of the code C is conflict, when C threads collide
  109. 109. Hintjens’ Law of Concurrency
  110. 110. Hintjens’ Law of Concurrency
  111. 111. Hintjens’ Law of Concurrency ZeroMQ: e=mc 2, for c=1
  112. 112. ZeroMQ Easy ... familiar socket API Cheap ... lightweight queues in a library Fast ... higher throughput than raw TCP Expressive ... maps to your architectureMessaging toolkit for concurrency and distributed systems.
  113. 113. geventExecution model
  114. 114. Threading vs EventedEvented seems to be preferred for scalable I/O applications
  115. 115. Evented Stack Non-blocking Code Flow Control I/O Abstraction Reactor I/O Loop Event Poller
  116. 116. 1 def lookup(country, search_term): 2 main_d = defer.Deferred() 3 4 def first_step(): 5 query = "http://www.google.%s/search?q=%s" % (country,search_term) 6 d = getPage(query) 7 d.addCallback(second_step, country) 8 d.addErrback(failure, country) 910 def second_step(content, country):11 m = re.search(<div id="?res.*?href="(?P<url>http://[^"]+)",12 content, re.DOTALL)13 if not m:14 main_d.callback(None)15 return16 url = m.group(url)17 d = getPage(url)18 d.addCallback(third_step, country, url)19 d.addErrback(failure, country)2021 def third_step(content, country, url):22 m = re.search("<title>(.*?)</title>", content)23 if m:24 title = m.group(1)25 main_d.callback(dict(url = url, title = title))26 else:27 main_d.callback(dict(url=url, title="{not-specified}"))2829 def failure(e, country):30 print ".%s FAILED: %s" % (country, str(e))31 main_d.callback(None)3233 first_step()34 return main_d
  117. 117. gevent “Regular” PythonGreenlets Monkey patching Reactor / Event Poller
  118. 118. Green threads“Threads” implemented in user space (VM, library)
  119. 119. Monkey patching socket, ssl, threading, time
  120. 120. Twisted
  121. 121. Twisted~400 modules
  122. 122. gevent25 modules
  123. 123. Performance http://nichol.as
  124. 124. Performance http://nichol.as
  125. 125. Performance http://nichol.as
  126. 126. Building a Networking App 1 #=== 2 # 1. Basic gevent TCP server 3 4 from gevent.server import StreamServer 5 6 def handle_tcp(socket, address): 7 print new tcp connection! 8 while True: 9 socket.send(hellon)10 gevent.sleep(1)1112 tcp_server = StreamServer((127.0.0.1, 1234), handle_tcp)13 tcp_server.serve_forever()
  127. 127. 1 #=== 2 # 2. Basic gevent TCP server and WSGI server 3 4 from gevent.pywsgi import WSGIServer 5 from gevent.server import StreamServer 6 7 def handle_http(env, start_response): 8 start_response(200 OK, [(Content-Type, text/html)]) 9 print new http request!10 return ["hello world"]1112 def handle_tcp(socket, address):13 print new tcp connection!14 while True:15 socket.send(hellon)16 gevent.sleep(1)1718 tcp_server = StreamServer((127.0.0.1, 1234), handle_tcp)19 tcp_server.start()2021 http_server = WSGIServer((127.0.0.1, 8080), handle_http)22 http_server.serve_forever()
  128. 128. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response(200 OK, [(Content-Type, text/html)]) 7 print new http request! 8 return ["hello world"] 910 def handle_tcp(socket, address):11 print new tcp connection!12 while True:13 socket.send(hellon)14 gevent.sleep(1)1516 def client_connect(address):17 sockfile = create_connection(address).makefile()18 while True:19 line = sockfile.readline() # returns None on EOF20 if line is not None:21 print "<<<", line,22 else:23 break2425 tcp_server = StreamServer((127.0.0.1, 1234), handle_tcp)26 tcp_server.start()2728 gevent.spawn(client_connect, (127.0.0.1, 1234))2930 http_server = WSGIServer((127.0.0.1, 8080), handle_http)31 http_server.serve_forever()
  129. 129. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response(200 OK, [(Content-Type, text/html)]) 7 print new http request! 8 return ["hello world"] 910 def handle_tcp(socket, address):11 print new tcp connection!12 while True:13 socket.send(hellon)14 gevent.sleep(1)1516 def client_connect(address):17 sockfile = create_connection(address).makefile()18 while True:19 line = sockfile.readline() # returns None on EOF20 if line is not None:21 print "<<<", line,22 else:23 break2425 tcp_server = StreamServer((127.0.0.1, 1234), handle_tcp)26 http_server = WSGIServer((127.0.0.1, 8080), handle_http)27 greenlets = [28 gevent.spawn(tcp_server.serve_forever),29 gevent.spawn(http_server.serve_forever),30 gevent.spawn(client_connect, (127.0.0.1, 1234)),31 ]32 gevent.joinall(greenlets)
  130. 130. ZeroMQ in gevent?
  131. 131. 1 from gevent import spawn 2 from gevent_zeromq import zmq 3 4 context = zmq.Context() 5 6 def serve(): 7 socket = context.socket(zmq.REP) 8 socket.bind("tcp://localhost:5559") 9 while True:10 message = socket.recv()11 print "Received request: ", message12 socket.send("World")1314 server = spawn(serve)1516 def client():17 socket = context.socket(zmq.REQ)18 socket.connect("tcp://localhost:5559")19 for request in range(10):20 socket.send("Hello")21 message = socket.recv()22 print "Received reply ", request, "[", message, "]"2324 spawn(client).join()
  132. 132. Actor model?Easy to implement, in whole or in part, optionally with ZeroMQ
  133. 133. What is gevent missing?
  134. 134. What is gevent missing? Documentation
  135. 135. What is gevent missing? Documentation Application framework
  136. 136. gserviceApplication framework for gevent
  137. 137. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 def handle_http(env, start_response): 6 start_response(200 OK, [(Content-Type, text/html)]) 7 print new http request! 8 return ["hello world"] 910 def handle_tcp(socket, address):11 print new tcp connection!12 while True:13 socket.send(hellon)14 gevent.sleep(1)1516 def client_connect(address):17 sockfile = create_connection(address).makefile()18 while True:19 line = sockfile.readline() # returns None on EOF20 if line is not None:21 print "<<<", line,22 else:23 break2425 tcp_server = StreamServer((127.0.0.1, 1234), handle_tcp)26 http_server = WSGIServer((127.0.0.1, 8080), handle_http)27 greenlets = [28 gevent.spawn(tcp_server.serve_forever),29 gevent.spawn(http_server.serve_forever),30 gevent.spawn(client_connect, (127.0.0.1, 1234)),31 ]32 gevent.joinall(greenlets)
  138. 138. 1 from gevent.pywsgi import WSGIServer 2 from gevent.server import StreamServer 3 from gevent.socket import create_connection 4 5 from gservice.core import Service 6 7 def handle_http(env, start_response): 8 start_response(200 OK, [(Content-Type, text/html)]) 9 print new http request!10 return ["hello world"]1112 def handle_tcp(socket, address):13 print new tcp connection!14 while True:15 socket.send(hellon)16 gevent.sleep(1)1718 def client_connect(address):19 sockfile = create_connection(address).makefile()20 while True:21 line = sockfile.readline() # returns None on EOF22 if line is not None:23 print "<<<", line,24 else:25 break2627 app = Service()28 app.add_service(StreamServer((127.0.0.1, 1234), handle_tcp))29 app.add_service(WSGIServer((127.0.0.1, 8080), handle_http))30 app.add_service(TcpClient((127.0.0.1, 1234), client_connect))31 app.serve_forever()
  139. 139. 1 from gservice.core import Service 2 from gservice.config import Setting 3 4 class MyApplication(Service): 5 http_port = Setting(http_port) 6 tcp_port = Setting(tcp_port) 7 connect_address = Setting(connect_address) 8 9 def __init__(self):10 self.add_service(WSGIServer((127.0.0.1, self.http_port), self.handle_http))11 self.add_service(StreamServer((127.0.0.1, self.tcp_port), self.handle_tcp))12 self.add_service(TcpClient(self.connect_address, self.client_connect))1314 def client_connect(self, address):15 sockfile = create_connection(address).makefile()16 while True:17 line = sockfile.readline() # returns None on EOF18 if line is not None:19 print "<<<", line,20 else:21 break2223 def handle_tcp(self, socket, address):24 print new tcp connection!25 while True:26 socket.send(hellon)27 gevent.sleep(1)2829 def handle_http(self, env, start_response):30 start_response(200 OK, [(Content-Type, text/html)])31 print new http request!32 return ["hello world"]
  140. 140. 1 # example.conf.py 2 3 pidfile = example.pid 4 logfile = example.log 5 http_port = 8080 6 tcp_port = 1234 7 connect_address = (127.0.0.1, 1234) 8 9 def service():10 from example import MyApplication11 return MyApplication() # Run in the foreground gservice -C example.conf.py # Start service as daemon gservice -C example.conf.py start # Control service gservice -C example.conf.py restart gservice -C example.conf.py reload gservice -C example.conf.py stop # Run with overriding configuration gservice -C example.conf.py -X http_port = 7070
  141. 141. Generalizinggevent proves a model that can be implemented in almost any language that can implement an evented stack
  142. 142. gevent Easy ... just normal Python Small ... only 25 modules Fast ... top performing server Compatible ... works with most librariesFuturistic evented platform for network applications.
  143. 143. Raiden Lightning fast, scalable messaginghttps://github.com/progrium/raiden
  144. 144. Concurrency modelsTraditional multithreadingAsync or Evented I/OActor model
  145. 145. ConclusionTwo very simple, but very powerful tools for distributed / concurrent systems
  146. 146. Thanks @progrium

×