storehaus icon indicating copy to clipboard operation
storehaus copied to clipboard

UpdatableStore

Open avibryant opened this issue 12 years ago • 6 comments

What do you guys think about something like

trait UpdatableStore[K,V] extends Store[K,V] {
  def update(k : K)(fn : V => Option[V]) : Future[Option[V]]
}

Where the semantics are that this would be an atomic update (so this makes sense for redis, mysql, etc where there's a notion of transactions or locks... presumably not for memcache).

This would be a good primitive to build MergeableStore implementations on top of that don't require specific backends.

avibryant avatar May 11 '13 20:05 avibryant

I wonder if it could look like the WithPutTtl trait mentioned on one of the other threads so that it just informs the semantics of an existing interface instead of adds a new method for puting a new value into a store.

trait WithAtomicPuts[K, V, S <: Store[K, V]] {
  def atomic: S
}

So you could somehow leave it up to the store to update its put implementation when requested though the atomic interface

  store.withPutTtl(10).atomic.put((key, Some(value)))

Something like that.

softprops avatar May 13 '13 16:05 softprops

Hm, I'm not following. The semantics I'm looking for are an atomic read->modify->write. For Redis it would look something like this (with some kind of configurable retry logic, maybe):

client.watch(List(key)).flatMap { unit =>
  client.get(key).flatMap { oldValue =>
    val newValue = fn(oldValue)
    client.transaction(List(SetCommand(key, newValue)))
  }
}

avibryant avatar May 13 '13 16:05 avibryant

ah, gotcha.

softprops avatar May 13 '13 16:05 softprops

I like it. I think @johnynek touched upon a similar idea specific to mysql in https://github.com/twitter/storehaus/issues/85

rubanm avatar May 13 '13 17:05 rubanm

I like it.

I think you can do this for memcache with CAS actually.

johnynek avatar May 13 '13 21:05 johnynek

Ah cool, didn't know memcache had CAS. I'll take this.

avibryant avatar May 13 '13 21:05 avibryant