DZone
Performance Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Performance Zone > Put on Your Monocle and Do Some Async Programming

Put on Your Monocle and Do Some Async Programming

Mitch Pronschinske user avatar by
Mitch Pronschinske
·
Jul. 28, 10 · Performance Zone · Interview
Like (0)
Save
Tweet
7.34K Views

Join the DZone community and get the full member experience.

Join For Free
Greg and Steven Hazel from Sauce Labs have recently built what they call, "An async programming framework with a blocking look-alike syntax".  This framework, named Monocle, is focused on being portable between event-driven I/O frameworks.  Currently, Monocle supports the Twisted and Tornado frameworks.

For those who haven't heard of Sauce Labs, they were co-founded by John Huggins, the creator of Selenium.  Sauce Labs' free and commercial tools build on top of the core Selenium testing framework.

The emergence of Monocle could indicate that Sauce Labs is taking a more focused look at event-driven code and its role in concurrent web performance.  Event-driven code is efficient and intuitive, but sometimes procedures are are split up and code is expanded in a not-so-good way.  

Anytime you do I/O, you have to register a new handler and then return to the event loop so that you can let other things happen while the I/O finishes.  Hazel and Hazel said, "It would be nice if we had some way to tell the event loop to call back into the middle of our function, so we could just continue where we left off."  In Python, they found a mechanism that can do just that.  

The mechanisms are called generators, and Monocle uses this Python syntax supported by Python 2.5 and up.  The generators in Monocle straighten out event-based code such as this blocking code (expanded into four functions):
def get_cmd(conn):
conn.read_until("\n", callback=handle_cmd)

def handle_cmd(conn, cmd):
if cmd.type == "get-address":
# keep track of the conn so we can write the response back!
def callback(result):
handle_user_query_result(conn, result)
db.query(cmd.username, callback)
else:
conn.write("unknown command")

def handle_user_query_result(conn, user):
conn.write(user.address)
Which is transformed into code like this, via Monocle:
@_o
def do_cmd(conn):
cmd = yield conn.read_until("\n")
if cmd.type == "get-address":
user = yield db.query(cmd.username)
yield conn.write(user.address)
else:
yield conn.write("unknown command")
Sauce Labs believes Monocle will make code easier to work with than multi-threaded code, thanks to its "cooperative concurrency" approach.

Here's a basic Monocle program running two concurrent processes called "o-routines" using Tornado's event loop.  One process is an HTTP server, and the other makes an HTTP request:
import monocle
monocle.init("tornado")

from monocle.stack import eventloop
from monocle.stack.network import add_service
from monocle.stack.network.http import HttpClient, HttpHeaders, HttpServer, http_respond

@monocle.o
def hello_http(req):
content = "Hello, World!"
headers = HttpHeaders()
headers['Content-Length'] = len(content)
headers['Content-Type'] = 'text/plain'
yield http_respond(req, 200, headers, content)

@monocle.o
def request():
client = HttpClient()
resp = yield client.request('http://127.0.0.1:8088/')
print resp.code, resp.body

add_service(HttpServer(hello_http, 8088))
monocle.launch(request())
eventloop.run()
And instead of @monocle.o, you can use the don the monocle (@_o) as a shortcut:
from monocle import _o

@_o
def request():
client = HttpClient()
resp = yield client.request('http://127.0.0.1:8088/')
print resp.code, resp.body
Hazel and Hazel admit, "this violates Python's convention that underscores indicate variables for internal use. But rules are for breaking. Live a little."

Check out Monocle on GitHub.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • SQL GROUP BY and Functional Dependencies: a Very Useful Feature
  • API Security Tools: What To Look For
  • SQL Database Schema: Beginner’s Guide (With Examples)
  • 5 Myths of Kubernetes

Comments

Performance Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo