200-line custom asynchronous non-blocking Web framework and 200-line asynchronous web Framework

Source: Internet
Author: User

200-line custom asynchronous non-blocking Web framework and 200-line asynchronous web Framework

In the Python Web framework, Tornado is famous for its asynchronous non-blocking. This article uses 200 lines of code to complete a micro asynchronous non-blocking Web Framework: Snow.

I. Source Code

This article is based on the non-blocking Socket and IO multiplexing to Implement Asynchronous non-blocking Web framework, among which is the internal principle of many asynchronous non-blocking Web frameworks.

#! /Usr/bin/env python #-*-coding: UTF-8-*-import reimport socketimport selectimport timeclass HttpResponse (object ): "encapsulate response information" "def _ init _ (self, content =''): self. content = content self. headers = {} self. cookies = {} def response (self): return bytes (self. content, encoding = 'utf-8') class HttpNotFound (HttpResponse): "" 404 error message "def _ init _ (self ): super (HttpNotFound, self ). _ init _ ('2014 Not Found ') class HttpRequest (object): "User encapsulation user request information" def _ init _ (self, conn): self. conn = conn self. header_bytes = bytes () self. header_dict ={} self. body_bytes = bytes () self. method = "" self. url = "" self. protocol = "" self. initialize () self. initialize_headers () def initialize (self): header_flag = False while True: try: received = self. conn. recv (8096) failed t Exception as e: pinned ED = None if not passed ed: break if header_flag: self. body_bytes + = already ed continue temp = already ed. split (B '\ r \ n \ r \ n', 1) if len (temp) = 1: self. header_bytes + = temp else: h, B = temp self. header_bytes + = h self. body_bytes + = B header_flag = True @ property def header_str (self): return str (self. header_bytes, encoding = 'utf-8') def initialize_headers (self): headers = self. header_str.split ('\ r \ n') first_line = headers [0]. split ('') if len (first_line) = 3: self. method, self. url, self. protocol = headers [0]. split ('') for line in headers: kv = line. split (':') if len (kv) = 2: k, v = kv self. header_dict [k] = vclass Future (object): "encapsulates the callback function in asynchronous non-blocking mode and is ready?" def _ init _ (self, callback): self. callback = callback self. _ ready = False self. value = None def set_result (self, value = None): self. value = value self. _ ready = True @ property def ready (self): return self. _ readyclass TimeoutFuture (Future): "Asynchronous non-blocking timeout" def _ init _ (self, timeout): super (TimeoutFuture, self ). _ init _ (callback = None) self. timeout = timeout self. start_time = time. time () @ property def ready (self): current_time = time. time () if current_time> self. start_time + self. timeout: self. _ ready = True return self. _ readyclass Snow (object): "micro-Web framework class" def _ init _ (self, routes): self. routes = routes self. inputs = set () self. request = None self. async_request_handler = {} def run (self, host = 'localhost', port = 9999): "" event loop: param host: param port: return: "sock = socket. socket (socket. AF_INET, socket. SOCK_STREAM) sock. bind (host, port,) sock. setblocking (False) sock. listen (1, 128) sock. setblocking (0) self. inputs. add (sock) try: while True: readable_list, writeable_list, error_list = select. select (self. inputs, [], self. inputs, 0.005) for conn in readable_list: if sock = conn: client, address = conn. accept () client. setblocking (False) self. inputs. add (client) else: gen = self. process (conn) if isinstance (gen, HttpResponse): conn. sendall (gen. response () self. inputs. remove (conn) conn. close () else: yielded = next (gen) self. async_request_handler [conn] = yielded self. polling_callback () failed t Exception as e: pass finally: sock. close () def polling_callback (self): "traverses the callback function that triggers asynchronous non-blocking: return:" for conn in list (self. async_request_handler.keys (): yielded = self. async_request_handler [conn] if not yielded. ready: continue if yielded. callback: ret = yielded. callback (self. request, yielded) conn. sendall (ret. response () self. inputs. remove (conn) del self. async_request_handler [conn] conn. close () def process (self, conn): "processes the routing system and executes the function: param conn: return:" "self. request = HttpRequest (conn) func = None for route in self. routes: if re. match (route [0], self. request. url): func = route [1] break if not func: return HttpNotFound () else: return func (self. request)Snow. py 2. Use

1. Basic use

from snow import Snowfrom snow import HttpResponsedef index(request):    return HttpResponse('OK')routes = [    (r'/index/', index),]app = Snow(routes)app.run(port=8012)

2. asynchronous non-blocking: timeout

from snow import Snowfrom snow import HttpResponsefrom snow import TimeoutFuturerequest_list = []def async(request):    obj = TimeoutFuture(5)    yield objdef home(request):    return HttpResponse('home')routes = [    (r'/home/', home),    (r'/async/', async),]app = Snow(routes)app.run(port=8012)

3. asynchronous non-blocking: waiting

Custom operations can be completed based on the waiting mode

from snow import Snowfrom snow import HttpResponsefrom snow import Futurerequest_list = []def callback(request, future):    return HttpResponse(future.value)def req(request):    obj = Future(callback=callback)    request_list.append(obj)    yield objdef stop(request):    obj = request_list[0]    del request_list[0]    obj.set_result('done')    return HttpResponse('stop')routes = [    (r'/req/', req),    (r'/stop/', stop),]app = Snow(routes)app.run(port=8012)

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.