Hanuman - Scala / Akka / BlueEyes / sbt demo
This is an old project, using an ancient version of Scala, Akka and a web framework that is not longer used. I provide a modern version in the Introduction to Actors lecture of the Introduction to Scala course at ScalaCourses.com.
BlueEyes framework encapsulates Netty, which acts as a web container.
Hanuman application services are defined by the
including services for
JSON GET and
POST, and MongoDB.
HanumanService acts as a front-end for a hierarchy of Akka
(the mythological monkey god),
WorkVisor (an Akka
(which each contain a
Monkey and a
This application simulates the adage that a large number of monkeys typing long enough should eventually reproduce any
Monkey instances generate pages of semi-random text, and their
Critics compare the generated text to a
WorkVisor actors supervise the
WorkCells for a simulation.
HanumanService can support a multiplicity of simulaneous simulations,
Hanuman actor supervises
The simulation is sequenced by
Monkey actors generate a page (by default, 1000 characters) of random text per
in the hope that they can match some portion of the target document.
To start a simulation, a client first requests a new simulation ID from
TODO provide the ability to upload the document that the
Monkeys are to attempt to replicate for a simulation.
Before generating random text,
Monkeys are first trained with a
LetterProbabilities map of
Char->probability when they are constructed.
A simulation terminates when a maximum number of
ticks have occurred, or the target document has been replicated.
Monkeys are unaware of the document they are attempting to replicate, and they are unaware of how the
Critics are unaware of how
One might imagine ever-more-sophisticated
Monkeys working from a dictionary should outperform
Monkeys that just type random characters.
Critics send a
TextMatch message to the
WorkCell supervisor whenever a
generated text has a better match than before to a passage in the target document.
Each simulation is managed by a
Hanuman stores the most recent
TextMatch for the
WorkCell in a
which is defined as
Actor.Uuid -> TextMatch.
Refs are passed into each
WorkCell actor/ supervisor, which sets/gets result
values atomically using shared-nothing state.
Critics are computationally more expensive than
Because matches are statistally unlikely, and become exponentially less likely for longer sequences,
WorkCell are few.
This means that it is inexpensive to transmit results from a
Critic in a
WorkCell to its supervising
WorkVisor via an Akka message.
Clients that might poll for results require a different strategy; a result cache is returned to them,
and the cache is updated on each
tick by the
Hanuman actor supervisor.
HanumanService creates the
Hanuman actor/supervisor, and the
Hanuman constructor accepts an
Akka Ref to a
Simulations instance, which is a
simulationID -> TextMatchMap.
Getting values from the Ref and and setting new values are performed within an implicit software transaction, which is
computationally expensive and presents a possible choke point.
Marshalling changes via a sequence of
ticks reduces potential conflicts.
This project requires static assets to be served from one domain (preferably a content delivery network) and the application to be served from another domain. You can debug both servers locally if you wish.
Clone this git repo.
Compile the app and create a start script:
Set the PORT environment variable for the static content server:
Start the local static content server (only needed when debugging it):
Set the environment variables for the app server:
export PORT=8585 export MONGOLAB_URI=mongodb://127.0.0.1:27017/hello export CONTENT_URL=http://localhost:8080/
Start the app server:
Run the app:
Run Clients Against Local or Remote Service Instances
JSON service (without the correct
Content-Type headerthere will be no response).
curl --header "Content-Type:application/json" http://localhost:8585/json
testscript fully exercises the Hanuman web API. It can work against a local Hanuman service instance or a remote service instance at a specified URL. Sample usages:
./test ./test http://hollow-winter-3011.herokuapp.com
Run on Heroku
Mike Slinn has deployed the app to http://hollow-winter-3011.herokuapp.com/
You can deploy it to your own Heroku app instance this way:
You can set up AWS CloudFront to act as the content repository, or use another CDN.
Clone the git repo.
Install the Heroku client and set up ssh keys.
Authenticate with Heroku:
Create your new app instance on Heroku:
heroku create --stack cedar
Add your Heroku app instance as a remote git repository. Substitute your Heroku app instance for
git remote add heroku firstname.lastname@example.org:hollow-winter-3011.git
Set up a Heroku environment variable called
CONTENT_URLand point it to your content delivery network. See the Heroku docs
heroku config:add CONTENT_URL=http://mycdn.com:1234/blah
Push the Hanuman app to Heroku; it will automatically be (re)built and run.
git push heroku master
You can also manually run the
sbt console on Heroku:
heroku run sbt console