Skip to content

Instantly share code, notes, and snippets.

@fdemmer
Last active September 16, 2015 16:41
Show Gist options
  • Save fdemmer/20c192995f1695a8236c to your computer and use it in GitHub Desktop.
Save fdemmer/20c192995f1695a8236c to your computer and use it in GitHub Desktop.
Very primitive simulation of a caching cdn like cloudfront.
# -*- coding: utf-8 -*-
"""
Very primitive simulation of a caching cdn like cloudfront.
"""
import logging
import requests
import sys
from concurrent.futures import ThreadPoolExecutor
from functools import partial
from urlparse import urlunparse
import tornado.ioloop
import tornado.web
from cachecontrol import CacheControlAdapter
logging.basicConfig(
stream=sys.stdout,
level=logging.DEBUG,
format='%(asctime)s %(levelname)s %(name)s %(funcName)s(%(lineno)d): %(message)s'
)
log = logging.getLogger(__name__)
ORIGIN_HOST = 'localhost:8000'
CACHE_PORT = 9000
THREADS = 32
class MainHandler(tornado.web.RequestHandler):
def initialize(self, session=None):
self.session = session
def fetch_origin(self, callback=None):
thread_pool.submit(
self.session.get,
urlunparse(('http', ORIGIN_HOST, self.request.uri, '', '', ''))
).add_done_callback(
lambda future: tornado.ioloop.IOLoop.instance().add_callback(
partial(callback, future)
)
)
@tornado.web.asynchronous
def get(self):
def callback(future):
response = future.result()
self.set_header("Content-Type", response.headers['content-type'])
self.write(response.content)
self.finish()
self.fetch_origin(callback)
thread_pool = ThreadPoolExecutor(THREADS)
session = requests.Session()
session.mount('http://', CacheControlAdapter(
pool_connections=THREADS, pool_maxsize=THREADS
))
application = tornado.web.Application([
(r".*", MainHandler, dict(session=session)),
])
if __name__ == "__main__":
application.listen(CACHE_PORT)
tornado.ioloop.IOLoop.current().start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment