Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Highly concurrent EventMachine-based Web service access to Maxima in Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.

Maxima Expect Interface and Goliath HTTP Server and Rails/Javascript UI

Maxima computer algebra system (CAS) backend that is event driven using EventMachine for high concurrency per thread. Uses Goliath

Future Plans:

  • Each thread will use fibers to manage an asynchronous ConnectionPool of N maxima processes through ruby's Pty::expect in order to let other concurrent requests process through maxima backends while other maxima requests are waiting on I/O or on calculations
  • M event loop processes of the above can be run behind a reverse proxy for even higher concurrency
  • A rails (javascript-heavy) UI will communicate with these backends and use MathJAX to render beautiful math output on the client side rather than making the server produce and serve images
  • The project could also expose a HTTP API to maxima for other frontends
require "em-synchrony"

# use eventmachine watch to get notification when pipe has data to read, then use the select-based expect.rb to get data
# if this ends up blocking too long unnecessarily, we can use a different mechanism.  And if it would work, we could even use receive_data instead and simplify our lives
# This is still a work in progress...

# use an EventMachine-friendly expect rather than the select polling one
#require "expect-synchrony"
# use expect to drive maxima processes and get the results.
#require "maxima-expect"

# N = number of maxima processes in a connection pool for each EventMachine reactor process
# maxima processes need to be on same machine as this process (popen might deadlock because of the stdout buffering of maxima whereas a pty-connection can get the output right away)
# maybe maxima could be run across ssh on another machine, but that is currently not supported
N = 2
# M of these programs should get started, each in its own process, and they can all be joined via a reverse proxy such as HAProxy 

EventMachine.synchrony do
    mes = N) do

    multi =
    multi.add :a, mes.aexecute("tex(1+1);")
    multi.add :b, mes.aexecute("tex(1+1);")
    res = multi.perform

    p "Look ma, no callbacks, and parallel requests!"
    p res



The MIT License - Copyright (c) 2011 Ammon Christiansen

Something went wrong with that request. Please try again.