Slide 1

Slide 1 text

Realtime data visualization RethinkDB & Epoch

Slide 2

Slide 2 text

Ryan Paul RethinkDB Evangelist @segphault

Slide 3

Slide 3 text

Usage Scenarios • Business intelligence • Streaming analytics • System monitoring • Live location tracking

Slide 4

Slide 4 text

Why Realtime?

Slide 5

Slide 5 text

Why Realtime? because POLLING IS A BUMMER

Slide 6

Slide 6 text

Realtime Visualization Stack RethinkDB NodeJS Socket.io D3 Koa Vue Epoch Browser REST API

Slide 7

Slide 7 text

Track live updates with RethinkDB changefeeds

Slide 8

Slide 8 text

What is RethinkDB? • Open source database for building realtime web applications • NoSQL database that stores schemaless JSON documents • Distributed database that is easy to scale

Slide 9

Slide 9 text

Built for Realtime Apps • Subscribe to change notifications from database queries • No more polling — the database pushes changes to your app • Reduce the amount of plumbing needed to stream live updates

Slide 10

Slide 10 text

Subscribe to change notifications on database queries Changefeeds

Slide 11

Slide 11 text

r.table("users").changes() Changefeeds Track changes on the users table

Slide 12

Slide 12 text

Changefeeds • The changes command returns a cursor that receives updates • Each update includes the new and old value of the modified record

Slide 13

Slide 13 text

r.table("users") .filter({name: "Bob"}).delete() Changefeed output: { new_val: null, old_val: { id: '362ae837-2e29-4695-adef-4fa415138f90', name: 'Bob', ... } } Changefeeds

Slide 14

Slide 14 text

r.table("players") .orderBy({index: r.desc("score")}) .limit(3).changes() Track top three players by score Chain the changes command to an actual ReQL query: Changefeeds

Slide 15

Slide 15 text

Send live updates with Socket.io Messaging

Slide 16

Slide 16 text

What is Socket.io? • Realtime web framework • Supports communication between frontend and backend • Abstracts away network transport • Can send arbitrary JSON objects

Slide 17

Slide 17 text

What is Socket.io? • Officially supported NodeJS server implementation • Client libraries for native mobile platforms and frontend web apps • Third-party server implementations for other languages

Slide 18

Slide 18 text

Socket.io Server var server = require("http").createServer(); var io = require("socket.io")(server); server.listen(8000, () => console.log("Server started on port 8000")); io.on("connection", client => { client.emit("message", {text: "Hello World"}); });

Slide 19

Slide 19 text

Socket.io Client var socket = io(); socket.on("message", data => { console.log("Received message:", data.text); });

Slide 20

Slide 20 text

Display live data with Epoch graphing library

Slide 21

Slide 21 text

What is D3? • Library for building interactive data visualizations • Provides APIs for generating and manipulating SVG content • Extremely powerful but difficult to use

Slide 22

Slide 22 text

Realtime Challenges • Potential for very frequent drawing updates • Need to remove old data while painting new data • Increments for your axes can change dynamically

Slide 23

Slide 23 text

Epoch Realtime charting library for high performance visualizations

Slide 24

Slide 24 text

What is Epoch? • High-level library for realtime data visualizations • Builds on D3 but also uses to boost performance • Supports a fixed range of visualization types

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Realtime Line Graph var chart = $("#chart").epoch({ type: "time.line", axes: ["left", "bottom"], data: [ {label: "Writes", values: [...]}, {label: "Reads", values: [...]} ] });

Slide 27

Slide 27 text

Realtime Line Graph var server = require("http").createServer(); var io = require("socket.io")(server); var r = require("rethinkdbdash")(config.database); var bluebird = require("bluebird"); bluebird.coroutine(function*() { var stats = yield r.db("rethinkdb").table("stats") .get(["cluster"]).changes(); stats.each((err, item) => io.emit("stats", item)); })(); server.listen(8000, () => console.log("Server started on port 8000"));

Slide 28

Slide 28 text

Realtime Line Graph function timestamp() { return (new Date).getTime() / 1000; } var socket = io(); socket.on("stats", data => { var stats = data.new_val.query_engine; chart.push([ { time: timestamp(), y: stats.written_docs_per_sec}, { time: timestamp(), y: stats.read_docs_per_sec} ]); });

Slide 29

Slide 29 text

Realtime Pie Graph

Slide 30

Slide 30 text

Realtime Pie Graph var changes = yield r.table("votes").changes()("new_val"); changes.each((err, vote) => { io.to(`poll:${vote.poll}`).emit("vote", vote); }); ... io.on("connection", bluebird.coroutine(function*(client) { client.on("subscribe", (id, callback) => { r.table("polls").get(id).merge({ choices: r.row("choices").merge(c => ({ value: r.table("votes") .getAll(c("id"), {index: "choice"}).count() })) }).then(callback); client.join(`poll:${id}`); }); }));

Slide 31

Slide 31 text

Realtime Pie Graph created: function() { var client = io(); client.on("vote", this.updateVote); client.on("connect", () => client.emit("subscribe", this.id, this.setup)); }, methods: { setup: function(data) { this.poll = data; this.chart = $("#vote-pie").epoch({ type: "pie", inner: 90, data: data.choices}); }, updateVote: function(vote) { this.poll.choices.find(c => c.id == vote.choice).value += 1; this.chart.update(this.poll.choices); ...

Slide 32

Slide 32 text

Additional Resources • RethinkDB website:
 http://rethinkdb.com • Epoch:
 https://fastly.github.io/epoch/ • Socket.io:
 http://socket.io/