Announcing the RethinkDB 2.0 release candidate

The RethinkDB 2.0 release candidate is now available for testing. RethinkDB 2.0 is designed to make building and scaling realtime apps dramatically easier. The upcoming 2.0 launch is an important milestone, marking our very first production-ready release. We'll announce commercial support options and other services alongside the release.

After five years of development, RethinkDB is ready for widespread adoption with the upcoming 2.0 release. The cumulative development effort behind the project includes more than 2,000 improvements, implemented across 16 major releases. Our most recent release, RethinkDB 1.16, dramatically expanded the changes command and introduced powerful support for building realtime web applications.

In addition to performance and stability improvements, the 2.0 release candidate also includes some noteworthy new features that complement the realtime functionality we introduced in the 1.16 release:

  • Support for attaching a changefeed to the get_all command.
  • Support for attaching a changefeed to the union command.
  • Optional EventMachine integration for performing asynchronous queries in the Ruby driver.
  • Optional Tornado integration for performing asynchronous queries in the Python driver.
  • A new feature in the cursor API that supports consuming the next element in a stream without blocking.

The EventMachine and Tornado integrations haven't landed in the client drivers yet, though the necessary backend features are already present. We'll issue new release candidate client drivers with full support for those features in the coming days.

This release candidate is intended for testing and evaluation purposes. We're eager to get feedback from users to help guide our efforts as we put the finishing touches on version 2.0. This is also a great opportunity for users to start exploring RethinkDB ahead of our big launch.

A growing number of users already deploy RethinkDB in production. We look forward to seeing the user community grow further in the coming months as our first production-ready release brings RethinkDB to a broader audience.

Help test the release candidate:

Join us online for a live RethinkDB workshop, hosted by Platzi

Join us Saturday, March 14 for a live RethinkDB training course. The two-hour workshop, taught by RethinkDB evangelist Ryan Paul and hosted online by our friends at Platzi, will teach you how to build realtime web applications with RethinkDB. The course is available for free—all you have to do is sign up.

The course includes:

  • An introduction to RethinkDB and distributed databases
  • A hands-on overview of ReQL, the RethinkDB query language
  • A guided intro to building realtime apps with RethinkDB and Node.js
  • An introduction to RethinkDB clustering and scalability best practices

Attend live to ask questions and participate interactively. If you can't make it for the live session, you will be able to watch the recorded video later.

Where: streamed live on Platzi (Register Here)

When: March 14, 2015 11:00AM - 1:00PM PT

Docker introduces official RethinkDB repository

Our friends at Docker recently added an official RethinkDB repository to the Docker Hub. They announced the new repo in a blog post yesterday, highlighting RethinkDB alongside several other prominent open source projects.

Docker is a tool that helps automate deployments. It takes advantage of platform-level container technology to make it easy to compose isolated software components in a reproducible way. A growing number of infrastructure-related tools, ranging from self-hosted PaaS environments to cluster management systems, are built around the Docker ecosystem.

You can run the following command to deploy RethinkDB from Docker's official repository:

$ docker run -d -P --name rethink1 rethinkdb

The images used in the official RethinkDB repository are maintained by community member Stuart Bentley, who is also responsible for the RethinkDB Dokku plugin that we wrote about last year.

After you get a RethinkDB container up and running with Docker, head over to our handy ten-minute guide to learn how to build applications with RethinkDB.

We're sponsoring AirPair's developer writing competition

We're teaming up with AirPair to support their $100k developer writing competition. We've sponsored a $500 cash prize to honor the best RethinkDB post submitted to the contest.

AirPair, which provides a service that connects developers with experts for live programming sessions, recently introduced an experimental set of social authoring features that make it possible for authors and readers to collaborate on content. AirPair's social authoring platform uses a GitHub-based workflow that involves forking and pull requests. They launched a writing competition to highlight the experiment and encourage developers to give it a try.

Over the next twelve weeks, you can win your share of $100,000 in prize money for producing the best tutorials, opinion pieces, and hands-on reports about your experiences using RethinkDB in production.

Have you built a project that involved RethinkDB? Do you have a compelling revelation to share about how RethinkDB can simplify realtime application architecture? If so, consider writing an article for AirPair to share your experience with other RethinkDB developers.

An article published on AirPair will reach a wide audience of developers. The average post published on the site in January received over 15,000 views—it's a great way to shine a spotlight on your work.

Visit the AirPair site to submit your post.

Build an IRC bot in Go with RethinkDB changefeeds

Dan Cannon's GoRethink project is among the most popular and well-maintained third-party client drivers for RethinkDB. Dan recently updated the driver to make it compatible with RethinkDB 1.16, adding support for changefeeds. The language's native concurrency features make it easy to consume changefeeds in a realtime Go application.

To see GoRethink in action, I built a simple IRC bot that monitors a RethinkDB cluster and sends notifications to an IRC channel when issues are detected. I built the bot with Go, using Dan's driver and an IRC client library called GoIRC.

Monitor the issues table

As I described in my last blog post, RethinkDB 1.16 introduced a new set of system tables that you can use to monitor and configure a RethinkDB cluster. You can interact the system tables using ReQL queries, just like you would with any other RethinkDB table.

The current_issues table contains a list of problems that currently affect the operation of the cluster. RethinkDB adds items to this table when servers drop from the cluster or other similar incidents occur. When a user intervenes to resolve an issue, the cluster will remove it from the table.

RethinkDB changefeeds provide a way to subscribe to a stream of realtime database updates. I used the following Go code to attach a changefeed to the current_issues table, watching for new issues that are characterized as critical. When issues are found, it prints them to the terminal:

type Issue struct {
    Description, Type string
}

db, err := r.Connect(r.ConnectOpts{Address: "localhost:28015"})
if err != nil {
    log.Fatal("Database connection failed:", err)
}

issues, _ := r.Db("rethinkdb").Table("current_issues").Filter(
    r.Row.Field("critical").Eq(true)).Changes().Field("new_val").Run(db)

go func() {
    var issue Issue
    for issues.Next(&issue) {
      if issue.Type != "" {
        log.Println(issue.Description)
      }
    }
}()

The ReQL expression uses the filter command to match only the issues in which the critical property carries the value true. The changefeed attached to the query will only emit documents that match the filter condition.

When consuming the output of the changefeed, you can wrap the handler in a goroutine (as demonstrated in the code example above) so that it will operate asynchronously in the background instead of blocking execution. Using goroutines and channels for asynchronous programming can simplify the architecture of your realtime application.

The Go driver can unmarshal JSON data returned by your ReQL queries and map the document properties to struct fields. In the example above, I defined a struct called Issue that has Description and Type fields. When I use the Next method to pull a document from the changefeed and assign it to a variable of type Issue, the fields map to the document properties with the same names. You can also optionally use struct field tags to manually associate fields with specific properties.

Make an IRC bot

The GoIRC library makes it relatively easy to create a simple IRC bot. The following code connects to an IRC server and instructs the bot to join a specific channel:

ircConf := irc.NewConfig("mybot")
ircConf.Server = "localhost:6667" 
bot := irc.Client(ircConf)

bot.HandleFunc("connected", func(conn *irc.Conn, line *irc.Line) {
    log.Println("Connected to IRC server")
    conn.Join("#mychannel")
})

To make the IRC bot push cluster issue notifications into the desired channel, I just had to add a few lines to the changefeed handler in the previous code example:

issues, _ := r.Db("rethinkdb").Table("current_issues").Filter(
    r.Row.Field("critical").Eq(true)).Changes().Field("new_val").Run(db)

go func() {
    var issue Issue
    for issues.Next(&issue) {
        if issue.Type != "" {
            text := strings.Split(issue.Description, "\n")[0]
            message := fmt.Sprintf("(%s) %s ...", issue.Type, text)
            bot.Privmsg("#mychannel", message)
        }
    }
}()

I also wanted to give my bot the ability to handle some basic commands from the user. Specifically, I wanted the program to continue running until a user in the IRC channel tells the bot to quit. I created a handler for the privmsg event and set up a channel to keep the bot running until it receives the command:

quit := make(chan bool, 1)

...

bot.HandleFunc("privmsg", func(conn *irc.Conn, line *irc.Line) {
    log.Println("Received:", line.Nick, line.Text())
    if strings.HasPrefix(line.Text(), config.IRC.Nickname) {
        command := strings.Split(line.Text(), " ")[1]
        switch command {
        case "quit":
            log.Println("Received command to quit")
            quit <- true
        }
        ...
    }
})

...

<- quit

I used a switch statement so that I can easily introduce new commands in the future by adding additional cases that match other strings. For now, I'll keep it simple. The whole bot is implemented in just 80 lines of code, which you can see on GitHub. You can easily adapt this example to make IRC bots that pipe any data you want from your RethinkDB applications into an IRC channel.

Build realtime web apps with Go and RethinkDB

IRC integration is a great exercise, but I also wanted to see what it is like to build realtime web applications with the Go driver. I decided to build a Go version of the simple cluster monitoring application that I demonstrated in my previous blog post.

The new version written in Go is just as succinct as the original Node.js implementation. I used a third-party Socket.io library to broadcast data from a changefeed that monitors RethinkDB's stats table:

server, _ := socketio.NewServer(nil)

conn, _ := r.Connect(r.ConnectOpts{Address: "localhost:28015"})
stats, _ := r.Db("rethinkdb").Table("stats").Filter(
    r.Row.Field("id").AtIndex(0).Eq("cluster")).Changes().Run(conn)

go func() {
    var change r.WriteChanges
    for stats.Next(&change) {
        server.BroadcastTo("monitor", "stats", change.NewValue)
    }
}()

http.Handle("/socket.io/", server)
http.Handle("/", http.FileServer(http.Dir("public")))
log.Fatal(http.ListenAndServe(":8091", nil))

The frontend, as detailed in the previous blog post, receives the data from Socket.io and graphs it in realtime with Fastly's Epoch library. You can see the complete source code of the Go version of the cluster monitoring demo on GitHub.

Concluding thoughts

Go is ostensibly a systems language, but it is fairly conducive to web application development. The Go library ecosystem has much of what you need to build modern web applications, including template processors and URL routing frameworks.

Working with JSON in conventional statically-typed languages is often a painful exercise—but it's not as painful in Go, because you can naturally map complex JSON documents to nested structs. That capability is fairly compelling when working with the output of ReQL queries.

If you'd like to see a more complete example of a realtime web application built with RethinkDB and Go, you can check out Dan's Todo List demo on GitHub.

Want to try it yourself? Install RethinkDB and check out the thirty-second quick start guide.

Resources: