Fast projections

Most EventStore client libraries allow you to subscribe to a stream by passing in a callback which is invoked when an event occurs (either a live or historic event). type Envelope = { Id : Int64 Event : Event Historic : bool } type EventOccurred = Envelope -> unit Let’s say we subscribe to a stream of a popular video service, and we want to project a read model that shows how many videos a viewer has watched. We don’t care about the bookmarked videos for now. ...

July 30, 2017 · 6 min · Jef Claes

Commands and events with JustSaying and AWS

I’ve been looking into handing a bit of our messaging infrastructure over to a managed alternative. Managing your own messaging infrastructure that should be highly available is not always an investment you want to make in this day and age. Going through the documentation and relying on experiences from some people I trust, I ended up looking at AWS and SNS/SQS. Making the Github repository rounds, looking for inspiration, I stumbled on JustSaying: a library by the people from JustEat implementing a message bus on top of AWS. ...

September 18, 2016 · 4 min · Jef Claes

Using a batch layer for fast(er) aggregations

In the oldest system I’m maintaining right now, we have an account aggregate that, next to mutating various balances, produces immutable financial transactions. These transactions are persisted together with the aggregate itself to a relational database. The transactions can be queried by the owner of the account in an immediate consistent fashion. The table with these transactions looks similar to this: CREATE TABLE [dbo].[Transaction] ( [Id] [int] IDENTITY(1,1) NOT NULL, [Timestamp] [datetime] NULL, [AccountId] [int] NOT NULL, [TransactionType] [varchar](25) NOT NULL, [CashAmount] [decimal](19, 2) NOT NULL, [BonusAmount] [decimal](19, 2) NOT NULL, [...] [...] () NULL /* Too much metadata I'm not very happy about */ CONSTRAINT [Tx_PK] PRIMARY KEY CLUSTERED ( [Id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY] ) ON [PRIMARY] There’s an index on the timestamp, the account identifier and the transaction type, which allows for fast enough reads for the most common access patterns which only return a small subset. ...

April 24, 2016 · 4 min · Jef Claes

Notifications from an event log

User notifications are a feature that came as an afterthought, but turned out to be rather easy to implement - without touching (read: breaking) existing functionality - thanks to having an immutable event log. In the domain I’m working in at the moment, we will often give users incentives to return to the website, or to extend their stay on the website. These incentives were only communicated by email at first, and this is a decent medium when you want users to return to the website. However, when you want to extend their stay on the website, you want to avoid users switching contexts between your website and their mail client. But also, as soon as they return to your website, you want to show them a crisp overview of all relevant calls to action. Having most calls to action map to a specific page, the list of notifications can serve as a one-click starting point, lowering the hurdle to browse to a relevant page. ...

April 17, 2016 · 4 min · Jef Claes

Functional one-liner for running totals in C#

Visualizing some data earlier this week I had to compute the running total of a sequence of numbers. For example, if the input sequence was [ 100; 50; 25 ] the result of the computation would be a new sequence of [ 100; 150; 175 ]. Muscle memory made me take a procedural approach, which works, but made me wonder if I could get away with less lines of code and without mutable state. ...

March 28, 2016 · 2 min · Jef Claes

Visualizing event streams

In my recent talk on Evil by Design, I showed how I’ve been visualizing event streams as a means to get a better grip on how aggregates behave in production. The talk’s scope kept me from showing the code that goes together with the examples shown. Consider this post as an addendum to that talk. First off, we need a few types: a string that identifies a stream, an event containing a timestamp and its name. A stream which is a composition of an identifier and a sequence of events. We also need a function that’s able to read a stream based on its identifier. ...

December 20, 2015 · 4 min · Jef Claes

Bulk SQL projections with F# and type providers

Early Summer, I had to set up an integration with an external partner. They required of us to daily provide them with a relational dataset stored in SQL Server. Most, if not all of the data was temporal, append-only by nature; think logins, financial transactions.. Since the data required largely lived in an eventstore on our end, I needed fast bulk projections. Having experimented with a few approaches, I eventually settled on projections in F# taking advantage of type providers. ...

October 18, 2015 · 4 min · Jef Claes

Aspect ratio calculation

Earlier today I was writing a migration script in F# where I had to calculate the aspect ratio based on the given screen dimensions. This is one of those problems where I don’t even mind breaking my head over, but directly head over to Stackoverflow to find an accepted answer which I can just copy paste. Since I didn’t find an F# snippet I could use, I ported some JavaScript, and embedded the result below for future snippet hunters. ...

September 11, 2015 · 1 min · Jef Claes

Basic casino math

In a previous series of posts, I went over the models used by casinos to spin a wheel (spinning, manipulating the odds, clustering and near misses). I did not yet expand on the basic mathematical models that ensure a casino makes money. Let’s pretend we are spinning the wheel again. The wheel has 5 pockets, and just one of those is the winning one. Given we will be using an unmodified wheel, you win 1 out of 5 spins. Each bet costs you 1 euro. Looking at the true odds (1/5), the casino should pay out 4 euro for you to break even. ...

June 22, 2015 · 3 min · Jef Claes

Consumed: Queries and projections (F#)

This is the third post in my series on porting a node.js application to an F# application. So far, I’ve looked at parsing command line arguments, handling commands and storing events. Today, I want to project those events into something useful that can be formatted and printed to the console. In the original application, I only had a single query. The result of this query lists all items consumed grouped by category, sorted chronologically. ...

May 24, 2015 · 3 min · Jef Claes