Modeling basic counters/sequences

Probably a silly question but how would you model basic counters?

Let’s say I have basket-N and I need N to start from 0 and be sequential.

I did it using a counter stream with ‘IncrementedCounter’ event (which I assume is more like ‘CreatedNewBasketId’ event) and now I just count up the events and that’s how I know that there are that many baskets and I can look for any basket within that counter and it should be there.

This seems ok but a bit smelly.

I guess I could also store actual incremented Id in every ‘CreatedNewBasketId’ and that gives it a bit more flexibility for processing and in case Ids need to be more than just a sequence of numbers.

So, what’s a proper way of doing something like that (don’t do it in ES at all and use SQL? :slight_smile: ?

fromCategory(‘basket’)

.when({

$init : function() {

return {

count: 0,

baskets: []

}

},

“AkkaEventStore.Messages.Events.CreatedBasketEvent”: function(s, e) {

var count = s.count++;

s.baskets.push(e.body.PersistenceId);

}

})

Half a million baskets array ftw :slight_smile:

The pattern is normally to use a stream as a reservation of the
sequence eg. Insert "basketReserved" to "basketReservations" this will
give you back the sequence that it was assigned then basketCreated ->
baskets-{idyougot}

A-ha. Since I’m using Akka for this it’s abstracting things like giving back data (which would give me new Id).

I’ll try and figure out how to deal with that. Thanks Greg!

If you look in 3.5.0 a similar pattern is used for scavenge (its a
pretty common pattern). Basically its an "announcement stream" +
stream per item though you want to use it in a slightly different way.
This pattern is very common in event sourced applications.

Basically the pattern works like this:
On write: write first to announcement stream then write to stream/item
(note if you get a failure here on the second write everything is fine
as you just announced a non-existing stream). For your case you are
interested in the return value of the announcement stream which
happens to be a monotonically incrementing sequence to create the
second stream.

Then a subscriber can follow the announcement stream and get
notifications of the other streams that are created.

Note this pattern also works in a sharded environment.

Note that you alternatively invert this pattern and write a projection
that watches the stream/item and asynchronously writes to the
announcement stream instead of doing it up front.

Cheers,

Greg

Thanks.

I ended up creating this projection -

fromCategory(‘basket’)

.when({

$init : function() {

return {

count: 1

}

},

“AkkaEventStore.Messages.Events.CreatedBasketEvent”: function(s, e) {

var count = s.count++;

emit(“basketsCounter”, “Increment”, count)

}

})

On coordinating actor recovery I read the last written event and use that as my counter value. Every time a new basket is created it has to go through that counter. I just create a basket with counter+1 and projection creates a new Increment event with the latest count. This will work well with just one coordinator.

If this coordinator Actor needed to be distributed then I’d subscribe to basketsCounter stream on it and use that to increment the counter and keep it in sync. There are still obvious issues with that in case of partitioning but I think it will be good enough in my scenario for now.

Thanks.

Just remember that projections are async!

Yeap, keeping that in mind.

I guess in high load situation after a crash bad things might happen (if projection hasn’t caught up). Is there maybe a way to wait for projection to get into a ‘complete’ state? That way on recovery we have to wait for the projection to complete before we read last value.

Thanks.