bustle / radredis

Basic redis backed object modeling for Node.
19 stars 3 forks source link

[RFC] Transactions: provide a consistent interface for passing and sharing pipelines and multis #31

Open tylr opened 8 years ago

tylr commented 8 years ago

In order to solve the O(n) problem when fetching nested objects we should consider an interface / API for shared pipelines when fetching data.

There are a few known patterns for solving this problem, I think the best will be found through practical implementations. One approach would be providing a Promise like interface for queueing up fetches. Perhaps something that works similarly to Promise.spread() that provides a single multi or pipeline to an array of radredis calls...

Through es6 we could have an easy to use and understand interface that used object destructuring to implement transaction wide pipelines.

Radredis.tx(Person.all, [Post.find, [1,2,3]])

// Internally
function find(ids, { pipeline }) {
  // use the pipeline...
}

It also seems sensical to provide the pipeline to certain callbacks / transforms.

const transforms = { onFind: (person, { pipeline }) => ({
  person.findFriends({ pipeline })
}) }

More to come...

jqyu commented 8 years ago

I'm kinda worried about the complexity of creating a transaction handler. Especially since things get very complicated when trying to deserialize the response of an arbitrary redis pipeline, even more so when multis are introduced.

IMO the simplest solution (and what I've been doing so far) is to expose a fetch method used for batch fetching (ideally across models):

Radredis.fetch
  ( [ Post.fetch.find(1)
    , Post.fetch.find(2)
    , Person.fetch.all()
    , ...
    ] )
//  => [ post, post, [ person ], ... ]

From there, it's the client's responsibility to implement batching and per-request caching, using something like Dataloader