Updates from December, 2014 Toggle Comment Threads | Keyboard Shortcuts

  • Richard 4:31 pm on December 10, 2014 Permalink |  

    I’m now blogging over here 

    Sorry, I got fed up with wordpress, and moved to Jekyll on GitHub: http://richorama.github.io/

     
  • Richard 4:50 pm on December 9, 2014 Permalink |  

    Running Julia on Azure Websites 

    Warning: This is a complete hack

    screenshot

    TL;DR

    A node process hosts the julia server, and passes the name of the named pipe to it as an argument.

    Some Background on IISNode

    Azure websites hosts node.js apps with IISNode. This basically does two things, activate the node process, and forward HTTP requests to is using a named pipe.

    Websites doesn’t restrict you to hosting JavaScript files, in fact you can start any old binary. I have had some success in hosting Go on Websites before (using node to forward requests using CGI).

    Julia

    Julia is a language that’s been around for a couple of years. It’s general purpose, with a strength in mathematical programming. I really like the syntax, and it seems to fit with the way I think about programming.

    Julia has a web stack, with Morsel.jl as the ‘Sinatra like’ web framework. I’m playing around with some of my own ideas, built on the same stack. I’ve called it Jolt.jl.

    Julia sits on the same networking library (libuv) as node, so I thought it would be simple to get it running on Azure. I was wrong.

    Hosting on Azure Websites

    Let’s go through the steps I took to get it working.

    • You need to bring the Julia runtime with you, so copy the bin and lib folder from %HOME_DIRECTORY%\AppData\Local\Julia-0.3.2 into your repository.
    • You need to bring the packages too, so let’s copy them in as well from your %HOME_DIRECTORY%\.julia directory.
    • Delete all the .git folders from the packages, and remove all the .gitignore files.
    • We need to tell Julia to look locally for the packages, so you’ll need to add this line to the start of your program push!(LOAD_PATH, ".") (we’ll do this in a bit).
    • You need to rewrite part of the HTTPServer module, so it uses PipeServer instead of TcpServer. This allows us to respond to requests on the named pipe. This will look something like this:
    immutable HttpHandler
        handle::Function
        sock::Base.UVServer
        events::Dict
    
        HttpHandler(handle::Function) = new(handle, Base.PipeServer(), defaultevents)
    end
    
    • You’ll need to write a new run method, to bind your named pipe to the PipeServer:
    export run_pipe
    
    function run_pipe(server::Server, pipe::ASCIIString)
        id_pool = 0 # Increments for each connection
        sock = server.http.sock
        websockets_enabled = server.websock != nothing
        Base.uv_error("listen", !Base.bind(sock::Base.PipeServer, pipe))
        listen(sock)
        event("listen", server, 0)
    
        while true # handle requests, Base.wait_accept blocks until a connection is made
            client = Client(id_pool += 1, accept(sock))
            client.parser = ClientParser(message_handler(server, client, websockets_enabled))
            @async process_client(server, client, websockets_enabled)
        end
    end
    
    • Remove all traces of GnuTLS from HttpServer (remove the using statement and the run_https function). It’s more trouble than it’s worth!
    • Fix up paths in any deps.jl files which point to binaries on your local machine, and set to "D:\home\site\wwwroot\* instead.
    • Now you can write a program. I used my Jolt.jl framework, but you can use what you like…
    push!(LOAD_PATH, ".")
    
    using HttpServer
    using Jolt
    using JoltView
    using JoltJson
    
    app = jolt()
    
    app.get("/") do req, res, ctx
        "hello world"
    end
    
    http = HttpHandler(app.dispatch) 
    server = Server(http)
    run_pipe(server, ASCIIString(ARGS[1].data))
    
    • My attempts to start the program directly from IISNode failed. Instead I wrote a node app (server.js) to start the Julia App.
    var spawn = require('child_process').spawn;
    console.log("starting julia");
    
    var env = process.env;
    env["HOMEDRIVE"] = "C:";
    env["HOMEPATH"] = "\home\site\wwwroot";
    
    var julia = spawn('bin\julia.exe', 
        ["server.jl", process.env.port], 
        { 
            env : env,
            cwd : process.cwd()
        },
        function callback(error, stdout, stderr){
    
    });
    
    julia.stdout.on('data', function (data) {
      console.log(data);
    });
    
    julia.stderr.on('data', function (data) {
      console.log(data);
    });
    
    julia.on('close', function (code) {
      console.log('Julia exited with code ' + code);
    });
    
    • Note that it’s necessary to add a couple of missing environment variables when starting the process.
    • Push to Azure Websites and stand back!

    Alternatively, you can just clone my repo which seems to work.

     
c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel