Statuses is an experimental, extremely simple-minded microblogging infrastructure for internal use, basically created to have a small yet meaningful Clojure app to play with. Don't expect too much, certainly not something ready for production unless you're mainly interested in fiddling around with stuff.
lein run
to start the application, then access it at
http://localhost:8080 - some sample data is
auto-generated if the "database" is not foundlein test
to run the test suitelein uberjar
to
create a stand-alone .jar file that you can run with `java -jar
If you want to run the application from clojure REPL e.g. in IntelliJ IDEA, you can go like this:
user=>
(load-file "src/statuses/server.clj")
(ns statuses.server)
(-main nil)
This should start the server.
Statuses uses
Note that all these dependencies are fetched automatically when you
use lein run
for the first time, and are put into the uberjar for
deployment.
Given its very limited initial requirements at @innoQ (and to support its usability as a self-contained example), the most significant design decision within Statuses is that no database is used. Instead, all of the status updates are kept in memory and are persisted every minute. This works surprisingly well in terms of code simplicity, but will obviously scale only within limits. But if you assume 15k are needed for every 100 status updates, even a million of them would fit in 150MB of JSON (and probably something similar in memory, haven't checked yet).
If scaling problems arise, it's likely going to be because writing the DB to disk takes too long (though even that might be doubtful given today's disk speeds). Should that become a problem, a solution might be to combine the in-memory DB with an event-driven model, where the full memory dump is only written very rarely, but every status update is persisted immediately (essentially a transaction log). The full state could thus be restored from the events stored, adding yet another buzzword and turning this an event-sourcing model. But seeing how far one can get without actually using a "real" database is part of the experiment.
So there are currently no plans to change the db model, even though
refactoring the persistence into a Clojure protocol
might be
reasonable to allow others to implement different backends.
Currently, the structure of the whole program is still very simplistic and should probably be refactored soon. At the moment, code is split across the following namespaces and matching files:
statuses.server
: the server main entry pointstatuses.backend.core
: the in-memory data structure and related functionsstatuses.backend.json
: JSON utility functions for converting the
in-memory DB to and from JSONstatuses.backend.persistence
: functions to write and read the DB
to/from diskstatuses.backend.time
: utility functions for handling the
conversion of (localized) time stampsstatuses.views.common
: layouts (using Twitter Bootstrap) for the UIstatuses.views.main
: the actual UI elements for displaying HTML
(and JSON)statuses.views.atom
: function to provide an Atom 1.0 feed of
status updatesName | URL |
---|---|
JSON containing all updates | https://<BASE_URL>/statuses/updates?format=json |
RSS feed containing all updates | https://<BASE_URL>/statuses/updates?format=atom |
JSON containing mentions of a specific user | https://<BASE_URL>/statuses/updates?query=@<USERNAME>&format=json |
RSS feed containing mentions of a specific user | https://<BASE_URL>/statuses/updates?query=@<USERNAME>&format=atom |
HTML form to reply to a certain update | https://<BASE_URL>/statuses/updates/<ID>/replyform |
ServerInfo | https://<BASE_URL>/statuses/info |
The application expectes to find remote_user
header in the HTTP request. If none is found, the username will be set to "guest".
A user can create new update and delete updates created by himself as long as there are no replies to this update.
Copyright 2012-2014 innoQ Deutschland GmbH. Published under the Apache 2.0 license.