Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

xreq_channel now working with the http channel! Need to make sure tha…

…t code really is as simple as I've made it...
  • Loading branch information...
commit d18541a055d140405d713fff59896ebe3bfeac37 1 parent edd7029
james authored committed
View
57 IPython/frontend/html/kernelmanager.py
@@ -2,6 +2,7 @@
"""
import os
+import cgi
import time
import json
import Queue
@@ -10,23 +11,39 @@
from SocketServer import ThreadingMixIn
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+client_death = 30 # seconds without heartbeat that client considered dead
+
class CometManager(object):
+ """Tracks msg_id, client get requests for the Comet design pattern"""
def __init__(self):
self.clients = {}
def register(self, client_id):
- self.clients[client_id] = Queue.Queue()
+ self.clients[client_id] = [time.time(), Queue.Queue()]
- def get(self, client_id):
- return self.clients[client_id].get()
+ def __getitem__(self, client_id):
+ return self.clients[client_id][1]
def append(self, msg):
- for q in self.clients.values():
- q.put(msg)
+ """Add a message to the SUB queues across all tracked clients"""
+ for i in self.clients.keys():
+ dead_for = time.time() - self.clients[i][0]
+ #Remove client if no heartbeat, otherwise add to its queue
+ if dead_for > client_death:
+ print "Removing client %s: dead for %f"%(i, dead_for)
+ del self.clients[i]
+ else:
+ self.clients[i][1].put(msg)
def __contains__(self, client_id):
return client_id in self.clients
-
+
+ def heartbeat(self, client_id):
+ self.clients[client_id][0] = time.time()
+
+ def send(self, msg_type, *args):
+ return self.kernel_manager.xreq_channel.execute(*args)
+
manager = CometManager()
class IPyHttpHandler(BaseHTTPRequestHandler):
@@ -39,7 +56,7 @@ def do_GET(self):
self.end_headers()
#Manager.get blocks until a message is available
- json.dump(manager.get(path), self.wfile)
+ json.dump(manager[path].get(), self.wfile)
elif path == "notebook":
self.send_response(200)
self.send_header("Content-type", "text/html")
@@ -62,7 +79,23 @@ def do_GET(self):
self.end_headers()
def do_POST(self):
- raise NotImplementedError("POST is reserved for XREQ")
+ self.send_response(200)
+ self.send_header("Content-type", "application/json")
+ self.end_headers()
+
+ client_id = self.path.strip("/")
+ data = cgi.FieldStorage(fp=self.rfile,
+ headers=self.headers,
+ environ={'REQUEST_METHOD':'POST',
+ 'CONTENT_TYPE':self.headers['Content-Type'],
+ })
+
+ msg_type = data["type"].value
+ if msg_type == "heartbeat":
+ manager.heartbeat(client_id)
+ elif msg_type == "execute":
+ response = manager.send("execute_request", data["code"].value)
+ self.wfile.write(response)
class IPyHttpServer(ThreadingMixIn, HTTPServer):
pass
@@ -134,10 +167,14 @@ def call_handlers(self, since_last_heartbeat):
class HttpKernelManager(KernelManager):
""" A KernelManager that provides signals and slots.
"""
-
+
# Use Http-specific channel classes that emit signals.
sub_channel_class = Type(HttpSubSocketChannel)
xreq_channel_class = Type(HttpXReqSocketChannel)
rep_channel_class = Type(HttpRepSocketChannel)
hb_channel_class = Type(HttpHBSocketChannel)
-
+
+ def __init__(self, *args, **kwargs):
+ super(HttpKernelManager, self).__init__(*args, **kwargs)
+ #Give kernel manager access to the CometManager
+ manager.kernel_manager = self
View
31 IPython/frontend/html/notebook.html
@@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
@@ -8,8 +8,8 @@
<script type="text/javascript">
client_id = "/$client_id";
$.ajaxSetup({
- url:client_id,
- dataType:"json"
+ url: client_id,
+ dataType: "json"
})
function comet() {
$.ajax({
@@ -19,18 +19,43 @@
msg += json.content.data
else if (json.msg_type == "pyin")
msg += json.content.code
+ else if (json.msg_type == "pyout")
+ msg += json.content.data
$("#messages").append("<pre>"+msg+"</pre>")
comet()
}
})
}
+ function heartbeat() {
+ $.ajax({
+ type: "POST",
+ data: {client_id:client_id, type:"heartbeat"},
+ success: function() {
+ setTimeout(heartbeat, 10000)
+ }
+ })
+ }
+ function execute(code) {
+ $.ajax({
+ type: "POST",
+ data: {type:"execute", code:code}
+ })
+ }
$(document).ready(function() {
comet()
+ heartbeat()
+ $("#exec").keypress(function(e) {
+ if (e.which == 13) {
+ execute(e.target.value)
+ e.target.value = ""
+ }
+ })
})
</script>
</head>
<body>
<div id="messages"></div>
+ <input id="exec" style="width:100%" />
</body>
</html>
Please sign in to comment.
Something went wrong with that request. Please try again.