Tuesday, 3 September 2013

Building an assessment app in two days -- third commit.

The third commit puts in place the first Data Access Object for the database: UserDAO

This uses ReactiveMongo, which is a non-blocking database driver for MongoDB. That means that when the database is processing a query, the thread is not left waiting, but can get on with other tasks.

Each of the methods returns Ref.

You're probably getting a bit tired of seeing Ref everywhere, but if you glance over to the test, you should see how they can be chained together in a fairly easy to read style. (If you're familiar with Scala.)

For instance, in this snippet, you can read those for statements as sequential actions that happen one after another. They happen asynchronously, but in order. First we save the user, then we push a new session, then we fetch the user again using the session, and then we extract the name from the user we got back.

"push sessions correctly" in {      
  val u = UserDAO.unsaved.copy(name=Some("Cecily Cardew"))
  val returnedName = for (
    saved <- UserDAO.saveNew(u);      
    pushed <- UserDAO.pushSession(
      saved.itself, 
      ActiveSession(key="mysession")
    );
    fetched <- UserDAO.bySessionKey("mysession"); 
    name <- fetched.name
  ) yield name      

  returnedName.toFuture must be_==(
    Some("Cecily Cardew")
  ).await      
}

There are a few design decisions taking place in this commit.

  • User contains a sequence of active sessions.

    This is going to let us list your active sessions in the browser, and remotely log yourself out if you've left yourself logged in on another computer.

  • There's no save, only saveDetails and a lot of push.. methods.

    When we save a user, we don't want to overwrite the sessions -- in case a concurrent request is updating them while we're processing this save. (Whether or not it's concurrent within the database, there might be two requests from the browser in flight.)

    Accordingly, saveDetails does not update the active sessions or any of the other lists.

  • Password hashing is already in there

    Although we're not supporting log-in with passwords, the default classes in handy-appbase-core already create a salt and a hash method, so that it's easy to store passwords salted and encrypted. (This uses encryption that comes standard in the JVM)

No comments: