Skip to content

Instantly share code, notes, and snippets.

@migonzalvar
Created January 14, 2015 22:54
Show Gist options
  • Save migonzalvar/954e2ea06d2200487522 to your computer and use it in GitHub Desktop.
Save migonzalvar/954e2ea06d2200487522 to your computer and use it in GitHub Desktop.
PostgreSQL notifications with Psycopg2 and Eventlet (from http://initd.org/psycopg/articles/2010/12/01/postgresql-notifications-psycopg2-eventlet/)
import psycopg2
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
import eventlet
from eventlet import wsgi
from eventlet import websocket
from eventlet.hubs import trampoline
dsn = "dbname=test" # customise this
def dblisten(q):
"""
Open a db connection and add notifications to *q*.
"""
cnn = psycopg2.connect(dsn)
cnn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
cur = cnn.cursor()
cur.execute("LISTEN data;")
while 1:
trampoline(cnn, read=True)
cnn.poll()
while cnn.notifies:
n = cnn.notifies.pop()
q.put(n)
@websocket.WebSocketWSGI
def handle(ws):
"""
Receive a connection and send it database notifications.
"""
q = eventlet.Queue()
eventlet.spawn(dblisten, q)
while 1:
n = q.get()
print(n)
ws.send(n.payload)
def dispatch(environ, start_response):
if environ['PATH_INFO'] == '/data':
return handle(environ, start_response)
else:
start_response('200 OK',
[('content-type', 'text/html')])
return [page]
page = b"""
<html>
<head><title>pushdemo</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<style type="text/css">
.bar {width: 20px; height: 20px;}
</style>
<script>
window.onload = function() {
ws = new WebSocket("ws://localhost:7000/data");
ws.onmessage = function(msg) {
bar = $('#' + msg.data);
bar.width(bar.width() + 10);
}
}
</script>
</head>
<body>
<div style="width: 400px;">
<div id="red" class="bar"
style="background-color: red;">&nbsp;</div>
<div id="green" class="bar"
style="background-color: green;">&nbsp;</div>
<div id="blue" class="bar"
style="background-color: blue;">&nbsp;</div>
</div>
</body>
</html>
"""
if __name__ == "__main__":
listener = eventlet.listen(('127.0.0.1', 7000))
wsgi.server(listener, dispatch)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment