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

APIs made for mobile networks

APIs made for mobile networks

The Python and web development communities have gotten pretty good at writing REST APIs for browsers and desktop clients. But porting that to the high-latency wild-west of mobile networks requires a paradigm shift. Learn how you can speed up your mobile API using proven technologies - and avoid writing your own protocol!

Chris Ridenour

July 28, 2013
Tweet

Other Decks in Programming

Transcript

  1. 27 July 2013 PyOhio 2013 WHO AM I? • Long

    term interest in mobile and web at P&G, Rockfish, now my own startup
  2. 27 July 2013 PyOhio 2013 WHAT IS LISNR? • Mobile

    only, push based CMS powered by background high frequency audio decoding • Started on a bus. • Swedish House Mafia, J. Cole, Made in America, this talk.
  3. 27 July 2013 PyOhio 2013 WHAT’S WRONG WITH REST? •

    LISNR v0.1 written in almost pure REST • Django, Tastypie, Memcached • Too many network requests
  4. 27 July 2013 PyOhio 2013 BUT I HAVE LTE! •

    Cricket sells the iPhone now. • Even Verizon and AT&T, in major cities, your traffic may be routed across multiple state lines.
  5. 27 July 2013 PyOhio 2013 THE SIGNAL GOES WHERE? [1]

    http://calendar.perfplanet.com/2012/latency-in-mobile-networks-the-missing-link/
  6. 27 July 2013 PyOhio 2013 LATENCY, NOT BANDWIDTH • Mobile

    networks are renown for 500ms+ latency • Number one goal for a mobile API is to minimize the cost of latency
  7. 27 July 2013 PyOhio 2013 YEA, BUT I’M ON VERIZON

    • Most libraries limit concurrent requests • General rule is 6 on WiFi, 2 on mobile
  8. 27 July 2013 PyOhio 2013 ASSUMPTIONS • You’re in control

    of the API and client • Data is not real time • This is worth it (how “online” does your app need to be?)
  9. 27 July 2013 PyOhio 2013 Stay in control Work with

    third party APIs on your server
  10. 27 July 2013 PyOhio 2013 OPTION 1: GLOBAL DUMP •

    Use a single API call to replace local data on the device • JSON dump, SQLite database, compressed SQL log • Clients mirror the global dump
  11. 27 July 2013 PyOhio 2013 • Pros • Single HTTP

    Request • No orphaned data • Handles additions, updates and deletes OPTION 1: GLOBAL DUMP
  12. 27 July 2013 PyOhio 2013 • Cons • Will actually

    be bandwidth limited with large data • Could replace local changes • Read-only call, writes still have overhead OPTION 1: GLOBAL DUMP
  13. 27 July 2013 PyOhio 2013 • Notes • Our first

    solution with LISNR • Logins returned a “last updated” time • Easy win, not long term though. OPTION 1: GLOBAL DUMP
  14. 27 July 2013 PyOhio 2013 • Python Notes • Custom

    Django class-based view • Cache warmed by celery • Django database abstraction makes custom SQLite files possible OPTION 1: GLOBAL DUMP
  15. 27 July 2013 PyOhio 2013 OPTION 2: PIPELINING • HTTP

    Pipelining was made for this! [2] http://en.wikipedia.org/wiki/File:HTTP_pipelining2.svg
  16. 27 July 2013 PyOhio 2013 • Part of the HTTP

    1.1 specification • Different than keep-alive / persistence • Apple’s suggested method of improving network performance on mobile OPTION 2: PIPELINING
  17. 27 July 2013 PyOhio 2013 • Pros • Requests sent

    without waiting for response • Theoretically can provide a huge increase in speed OPTION 2: PIPELINING
  18. 27 July 2013 PyOhio 2013 • Cons • Responses must

    come in order of requests • Proxies will negate pipelining or worse • Most Python servers don’t support it OPTION 2: PIPELINING
  19. 27 July 2013 PyOhio 2013 Django==1.5 distribute==0.6.27 gevent==0.13.8 greenlet==0.4.0 gunicorn==0.17.2

    wsgiref==0.1.2 class DetailView(View): http_method_names = 'get' def get(self, request, *args, **kwargs): sleep(2) return HttpResponse( status=200, content_type='application/json', content=json.dumps({'data': '...about 1kb of data...'}) ) python manage.py run_gunicorn -k gevent_pywsgi OPTION 2: PIPELINING
  20. 27 July 2013 PyOhio 2013 Client Method Time to Complete

    (Average, 5x, 40 req) HTTP 25.74s HTTP Pipelining 25.62s OPTION 2: PIPELINING
  21. 27 July 2013 PyOhio 2013 • Notes • 40 requests,

    used default iOS connection pool (6 requests), server in Toyko • ~3850ms response time OPTION 2: PIPELINING
  22. 27 July 2013 PyOhio 2013 • Python Notes • Gevent

    supports pipelining • But only with pywsgi • Other servers may support it but “HTTP 1.1 compliant” doesn’t mean full support OPTION 2: PIPELINING
  23. 27 July 2013 PyOhio 2013 OPTION 3: WEBSOCKETS • Protocol

    written over TCP • Upgrades a HTTP request to a full socket connection • Increasing support in web servers • Supports standard HTTPS/TLS
  24. 27 July 2013 PyOhio 2013 • HTTP is a conversation

    • Socket connections are two people yelling at each other OPTION 3: WEBSOCKETS
  25. 27 July 2013 PyOhio 2013 class WSHandler(tornado.websocket.WebSocketHandler): def open(self): print

    "WebSocket opened, returning list" ... self.write_message(json.dumps(urls)) @gen.engine def on_message(self, message): print "Message: %s" % message response = yield gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time() + 2) self.write_message(json.dumps({'id': message[-2:], 'data': '...about 1kb of data...'})) def on_close(self): print "WebSocket closed" OPTION 3: WEBSOCKETS
  26. 27 July 2013 PyOhio 2013 Client Method Time to Complete

    (Average, 5x, 40 req) HTTP 25.74s HTTP Pipelining 25.62s Websockets 4.04s OPTION 3: WEBSOCKETS
  27. 27 July 2013 PyOhio 2013 • Pros • Starts as

    an HTTP request • Supported by nginx load balancing • Socket level speeds • Standard SSL encryption OPTION 3: WEBSOCKETS
  28. 27 July 2013 PyOhio 2013 • Cons • Requires your

    own protocol • Some proxies interrupt as well • Use WSS or WS over port 443 • To take full advantage, should be on an event based server OPTION 3: WEBSOCKETS
  29. 27 July 2013 PyOhio 2013 • So, is this comparison

    fair then? • Not really, but that’s okay • Real life comparison though • HTTP pipelining could have been an easy win • Pipelining still requires first request, first response OPTION 3: WEBSOCKETS
  30. 27 July 2013 PyOhio 2013 • What if I don’t

    want to write my own protocol? • “WAMP provides asynchronous RPC and PubSub over WebSocket” • HTTP-like endpoints, but really just structured messages • http://wamp.ws OPTION 3: WEBSOCKETS
  31. 27 July 2013 PyOhio 2013 • What are the best

    Python websocket libraries? • My personal favorite is Tornado • There are some general libraries • One that integrates WAMP is Autobahn • They also provide client libraries for mobile OPTION 3: WEBSOCKETS
  32. 27 July 2013 PyOhio 2013 KEEP BATTERY IN MIND •

    Even with the long latency, don’t keep connections open longer than you need • Continue to leverage the easy wins to keep time connected down
  33. 27 July 2013 PyOhio 2013 CURRENT PROCESS • Websocket opens

    with HEAD param: last_updated • Once upgraded, socket returns list of updated objects • We send our POST requests • Pull down all GET updates, clean up deleted objects • POST requests in celery queue have a reference to connection • If completed while connection open, send result / notification • Otherwise send data via push notification / GCM • Keep connection open after all GET for some timeout period