Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Non-blocking Python

Non-blocking Python

Slides for PyCon SG 2014


Tao Zhu

June 20, 2014


  1. Non-Blocking Python By Tao Zhu

  2. Tao Near 10 years exp as “full-stack” ! Lead Developer,

    Perform Group Plc
  3. Repeated Stories
 PM: Why slow? System Admin: Seems only slow

    during peak hour? Developer: Seems only slow for login? DevOps: It is slow in the login process as there are many concurrent write ops into db and db starts lock row.
  4. “DevOps” is killing Developers? Rise of “full-stack”? How to think

    like a “full-stack”?
  5. Developing beyond big O Developer: I have implemented a binary-

    tree algo that is O(log n) System Admin: I have implemented B+ tree index that is better than O(log n) DevOps: 1. The single table is just too big. Time to break down into smaller tables? 2. Is your web server blocking
  6. Blocking? What is that? A blocking web-server is similar to

    a phone call. ! You need to wait on-line to get a response and continue
  7. A blocking server Django Server Process Django Server Process Django

    Server Process Django Server Process DB Django Server Process = context switching (via kernel) O(logn)
  8. Non-blocking server Tornado Server Process DB = epoll (via kernel)

    O(1) Event loop
  9. How to write Non-block server? Call Backs Coroutine (Decorator) Yield

    (Lazy Eval) def wait_for_messages(self, callback, cursor=None): if cursor: new_count = 0 for msg in reversed(self.cache): if msg["id"] == cursor: break new_count += 1 if new_count: callback(self.cache[-new_count:]) return self.waiters.add(callback) ! def cancel_wait(self, callback): self.waiters.remove(callback) ! class MessageNewHandler(BaseHandler): @tornado.web.authenticated @gen.coroutine def post(self): message = { "id": str(uuid.uuid4()), "from": self.current_user["first_name"], "body": self.get_argument("body"), } ! cursor = collection.find({'$or': [{'teamA': self.get_argument("body")},{'teamB' new_message = [self.get_argument("body"),"Matches:"] withMatch = False while (yield cursor.fetch_next): document = cursor.next_object() withMatch = True try: matchDatetime = document.get('data').get('prematch').get('match').get(' except: try: matchDatetime = document.get('data').get('match').get('start_time') except: pass ! print matchDatetime msg_str = matchDatetime+':'+document.get('teamA','')+' v '+ document.get('t if isinstance(document.get('goalA'), int ): msg_str = msg_str+' '+str(document.get('goalA',''))+' : '+ str(document new_message.append(msg_str) !
  10. Non-blocking DB Driver Non-blocking through out the “Full Stack” PyMongo?

    No, it is blocking Use Motor
  11. Demo - World Cup Genie

  12. Take-aways How to think like a “Full-stack”? Look beyond coding

    and big(O) Blocking vs Non-Blocking Tornado Programming Essentials Callbacks,Coroutines, Yield Non-blocking Full Stack - Motor
  13. Contact Blog: Tzu’s {Code of Geeks} http://geektzu.wordpress.com/author/geektzu/ Email: software-engineer@outlook.com Github: