add initial .locked(key, fn)

cc @calvinfo 

how does that look ?
kinda hard to test, if you have any suggestions on more tests let me know.
maybe we should add a test that uses redis list and we can check that the events are in sorted order.
I wonder about this API a bit, partially because errors will cause the lock to stay locked until it times out and passing `fn` to `unlock` will cause whatever errors happen in `unlock` to be sent back with the integration (unless we wrap it in another function).

what if instead we made it so unlock doesn't take any arguments? instead you have to call it and the `fn`?

```js
function withLock(msg, _, fn){
  var self = this;
  this.lock(msg.userId(), function(err, unlock){
    if (err) return fn(err);
    db.hget('users', msg.userId(), function(err, value){
      if (err) return fn(err);
      if (value) return unlock() && fn(null, value);
      db.hset('users', msg.userId(), msg.event(), function(err){
        unlock();
        fn(err);
      });
   });
});
```

the potential downside I see is that teammates might forget to call `unlock`. we could add some sort of warning message if there locks timing out, or add something to the tester if there are outstanding locks when the tests finish.