Stream Locking to ensure single writes

Hi all,

Not sure if this has been asked or discussed, but I think I have a feature request that I am more than willing to try and implement.

We currently have one or more event repositories in our microservices depending on what the boundary defines.

We have come across some interesting behavior when using the actor pattern that we think might be usable in ESDB.

The actor pattern or specifically the framework we are using ensures that there can at most be one thread acting upon the actor, and the rest are queued. This I believe can be something that ESDB can provide on stream reads that will be used from a command side to write new events.

A sort of a lock that is placed on a stream for a specific reserved time and while this lock is active other readers can read the stream but not append to it.

I have a couple of ideas in mind, but thought one that might work quite well is a system event, like the tombstone event that gets written to a stream if the events were read for the purpose of rehydration of a aggregate that will be emitting more events.

For example then when ReadStreamAsync is used you are able to add an additional parameter in that specifies the stream should be locked from being read for a specified amount of time, which can also be supplied. The lock event will then be placed and when another requests the stream and exception of some sort can be thrown, or a retry policy can be used. If the first requester then either writes the new events or “unlocks” the stream before the the lock duration another event is written which unlocks the stream and then others can either request again or if a retry policy is used the next in line requester then gets the events and the lock is placed again.

I have a working example on our side, but this only abstracts from the current implementation, if this was baked into the actual SDK or ESDB it can be enforced.

This would then still allow other persistent subs and catchup subs to continue as normal as they are only reading events and don’t plan on changing the stream by emitting new events.

Was wondering if this was ever given thought and would it be something that can be supported? As I said we are more than willing in terms of creating a PR for this.

Apologies this post was also more targeting the netcore SDK, but if it is built into ESDB itself it would then be up to each SDK to implement its own logic for supporting this.

I know something similar can already be used with the expected stream version when writing or appending.

Apologies if I am not making any sense.

“I know something similar can already be used with the expected stream version when writing or appending.”

This is precisely where my thoughts went. It would seem you could do this from the outside if I am understanding things properly.

So we could have an event
StreamLocked { until : …}

So long as you used expected version on appends it would at least appear this could be built relatively easily on the outside.

There has also been discussion in the past about using metadata “immutable : true” or similar on a stream to prevent writes to it. You can kind of/sort of do this today using permissions and just take away the write permission on the stream but its a bit of “jumping through hoops” to do it and not the most intuitive way of approaching it.

Yes we abstract some functionality of ES into a reusable repository. Almost like DB Context in the EF world. The repository knows how to rebuild, version, append, encrypt, decrypt sensitive data, has custom Metadata enriches and snaphotting. Something I’ve been building for about 4 years now. Got most inspirations of one of your repo’s, think it was called simple cqrs or basic DDD.

Current implementation is in the repository, and will continue developing that out.

Will look into the permissions, just worried there will be a deadlock or something never releases.