Skip to content

Commit

Permalink
Heartbeat is executed in an independent thread, out cells can be high…
Browse files Browse the repository at this point in the history
…lighted when its html element has id=ipylua_static_code
  • Loading branch information
pakozm committed Oct 4, 2015
1 parent 9162294 commit f8e3e70
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 22 deletions.
85 changes: 63 additions & 22 deletions IPyLuaKernel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ end
local json = require "IPyLua.dkjson"
local zmq = require 'lzmq'
local zmq_poller = require 'lzmq.poller'
local zthreads = require "lzmq.threads"
local z_NOBLOCK, z_POLLIN = zmq.NOBLOCK, zmq.POLL_IN
local z_RCVMORE, z_SNDMORE = zmq.RCVMORE, zmq.SNDMORE
local zassert = zmq.assert
Expand Down Expand Up @@ -204,7 +205,7 @@ do
function(obj, MAX)
local tt,footer = type(obj)
if tt == "table" then
local tbl = {}
local tbl = { "{" }
do
local max = false
for k,v in ipairs(obj) do
Expand All @@ -226,12 +227,21 @@ do
if i >= MAX then max=true break end
end
if max then table.insert(tbl, "\t...") end
footer = ("# %s with %d array part, %d hash part"):format(tostring(obj), #obj, #keys)
footer = ("-- %s with %d array part, %d hash part"):format(tostring(obj), #obj, #keys)
end
table.insert(tbl, "}")
table.insert(tbl, footer)
return { ["text/plain"]=table.concat(tbl, "\n").."\n" }
local str = table.concat(tbl, "\n")
return {
["text/plain"]=str.."\n",
["text/html"]=('<code id="ipylua_static_code">%s</code>'):format(str),
}
else
return { ["text/plain"]=tostring(obj).."\n" }
local str = tostring(obj)
return {
["text/plain"]=str.."\n",
["text/html"]=('<pre>%s</pre>'):format(str),
}
end
end)

Expand Down Expand Up @@ -482,10 +492,7 @@ end
-- ZMQ Read Handlers

local function on_hb_read( sock )
-- read the data and send a pong
local data = zassert( sock:recv(zmq.NOBLOCK) )
-- TODO: handle 'timeout' error
sock:send('pong')

end

local function on_control_read( sock )
Expand All @@ -512,7 +519,7 @@ end
-- SETUP

kernel_sockets = {
{ name = 'heartbeat_sock', sock_type = zmq.REP, port = 'hb', handler = on_hb_read },
-- { name = 'heartbeat_sock', sock_type = zmq.REP, port = 'hb', handler = on_hb_read },
{ name = 'control_sock', sock_type = zmq.ROUTER, port = 'control', handler = on_control_read },
{ name = 'stdin_sock', sock_type = zmq.ROUTER, port = 'stdin', handler = on_stdin_read },
{ name = 'shell_sock', sock_type = zmq.ROUTER, port = 'shell', handler = on_shell_read },
Expand All @@ -522,24 +529,57 @@ kernel_sockets = {
local z_ctx = zmq.context()
local z_poller = zmq_poller(#kernel_sockets)
for _, v in ipairs(kernel_sockets) do
-- TODO: error handling in here
local sock = zassert( z_ctx:socket(v.sock_type) )
if v.name ~= "heartbeat_sock" then
-- TODO: error handling in here
local sock = zassert( z_ctx:socket(v.sock_type) )

local conn_obj = kernel.connection_obj
local addr = string.format('%s://%s:%s',
conn_obj.transport,
conn_obj.ip,
conn_obj[v.port..'_port'])
local conn_obj = kernel.connection_obj
local addr = string.format('%s://%s:%s',
conn_obj.transport,
conn_obj.ip,
conn_obj[v.port..'_port'])

zassert( sock:bind(addr) )

if v.name ~= 'iopub_sock' then -- avoid polling from iopub
z_poller:add(sock, zmq.POLLIN, v.handler)
end
zassert( sock:bind(addr) )
if v.name ~= 'iopub_sock' then -- avoid polling from iopub
z_poller:add(sock, zmq.POLLIN, v.handler)
end

kernel[v.name] = sock
kernel[v.name] = sock
end
end

-- heartbeat is controlled through an independent thread, allowing the main
-- thread to manage interactive commands given by the IPython
local thread = zthreads.run(z_ctx,
function(conn_obj, require, string, print)
local zmq = require "lzmq"
local z_ctx = require"lzmq.threads".get_parent_ctx()
local zassert = zmq.assert
local v = {
name = 'heartbeat_sock',
sock_type = zmq.REP,
port = 'hb',
}
local sock = zassert( z_ctx:socket(v.sock_type) )
local addr = string.format('%s://%s:%s',
conn_obj.transport,
conn_obj.ip,
conn_obj[v.port..'_port'])
zassert( sock:bind(addr) )
while true do
-- read the data and send a pong
local data,msg = sock:recv()
if msg ~= "timeout" then
if not data then break end
-- TODO: handle 'timeout' error
sock:send('pong')
end
end
end,
kernel.connection_obj, require, string, print)
thread:start(true,true)

-------------------------------------------------------------------------------
-- POLL then SHUTDOWN

Expand All @@ -550,3 +590,4 @@ for _, v in ipairs(kernel_sockets) do
kernel[v.name]:close()
end
z_ctx:term()
thread:join()
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ c.Session.key = b''
c.Session.keyfile = b''
```

* Copy the content of `config` folder into your
`~/.ipython/profile_IPyLua/static/custom/` folder.

* Invoke IPython with this Lua kernel:

```
Expand Down
10 changes: 10 additions & 0 deletions config/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* disable smoothing on images (needed to visualize filters) */
img {
image-rendering: optimizeSpeed;
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -o-crisp-edges; /* Opera */
image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
image-rendering: optimize-contrast; /* CSS3 Proposed */
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */

}
47 changes: 47 additions & 0 deletions config/custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
function checkDOMChange() {
$("#ipylua_static_code").each(
function() {
var $this = $(this),
$code = $this.html();
$this.empty();
var myCodeMirror = CodeMirror(this, {
value: $code,
mode: 'lua',
lineNumbers: false,
readOnly: true
});
}).attr("id", "highlighted_ipylua_static_code");
setTimeout( checkDOMChange, 500 );
}
checkDOMChange();

$([IPython.events]).on('notebook_loaded.Notebook', function(){
// add here logic that should be run once per **notebook load**
// (!= page load), like restarting a checkpoint
var md = IPython.notebook.metadata
if(md.language){
console.log('language already defined and is :', md.language);
} else {
md.language = 'lua' ;
console.log('add metadata hint that language is lua');
}
});

// logic per page-refresh
$([IPython.events]).on("app_initialized.NotebookApp", function () {
$('head').append('<link rel="stylesheet" type="text/css" href="custom.css">');


IPython.CodeCell.options_default['cm_config']['mode'] = 'lua';

CodeMirror.requireMode('lua', function() {
IPython.OutputArea.prototype._should_scroll = function(){return false}
cells = IPython.notebook.get_cells();
for(var i in cells){
c = cells[i];
if (c.cell_type === 'code') {
c.auto_highlight()
}
}
});
});

0 comments on commit f8e3e70

Please sign in to comment.