RethinkDB + Node via Dockhero
JavaScript Ruby HTML CSS
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
app
bin
config
db
lib
livestatus
log
public
tmp
vendor/assets
.gitignore
Gemfile
Gemfile.lock
README.md
Rakefile
config.ru
dockhero-compose.yml

README.md

RethinkDB + NodeJS as ActionCable alternative

An example Rails app which uses RethinkDB + NodeJS microservice to push background operation progress to the front-end. The progress is updated in the DB via NoBrainer ORM, and RethinkDB's changefeed is delivered to the front-end using Server-Sent Events (SSE) and rendered in the UI with RiotJS.

Try it yourself

The Ruby part of this example can be deployed to Heroku with the standard Git deployment flow. Once deployed, set RETHINKDB_PASSWORD heroku config var to something random

heroku config:set RETHINKDB_PASSWORD="some-random-secret-582"

Setting up RethinkDB + NodeJS microservice at Heroku can be done via Dockhero addon (see docs ). Please sign up for free alpha access at dockhero.io

heroku plugins:install dockhero
heroku addons:create dockhero
heroku dh:wait
heroku dh:compose up -d

Now everything should be up and running, and you can test the app:

heroku open

How it Works

In this example all the "magic" is happening in livestatus/server.js file, which acts as a "cable" between the Ruby-on-Rails back-end and RiotJS front-end. It streams a sequence of changes from RethinkDB database to front-end via SSE.

// livestatus/server.js
app.use(rethinkSse())  // a middleware which renders an SSE stream from RethinkDB's cursor

app.use(route.get("/operations/:id", function *(id) {
  const cursor = yield r.table("operations")
    .get(id)
    .changes({include_initial: true})
    .run(this._rdbConn);

  this.rethinkSse(cursor);
}));

On the Rails back-end, the changes are initiated with the following code in WelcomeController which updates an instance of Operation record in RethinkDB

# app/controllers/welcome_controller.rb
def do_something
  operation.progress += 1
  operation.save!
  render json: {status: 'OK'}
end

On the client, the SSE stream is consumed in app/assets/javascripts/progressor.tag using Rx.DOM.fromEventSource RxJS extension.

// app/assets/javascripts/progressor.tag
var source = Rx.DOM.fromEventSource(opts.feed_url).map(function(data) {
  return JSON.parse(data);
});

var subscription = source.subscribe(function(data) {
  this.update({progress: data.progress})
}.bind(this));