hubertlepicki

hubertlepicki

Debouncing and aggregating events across cluster nodes

I have a system that emits events, such as:

"record_updated", id: 6, company_id: 1
"record_updated", id: 2, company_id: 2
"record_updated", id: 4, company_id: 1

These events are currently dispatched through Phoenix PubSub, from nodes in an Elixir cluster, and either through Channels or GraphQL subscriptions (Absinthe) get delivered to clients who react appropriately to these updates.

The problem is the amount of traffic, and number of updates.

I would like to debounce these events and group by company_id and only emit them when the updates stop or a configured time period is reached.

So, if the events happen constantly, we would emit one event per company_id, having a list of IDs, rather than single ID in their payload, once every 10s or so.

If there was just one event, I think I’d like to wait like a second and emit it to the client as soon as possible.

For example, given the above 3 events, I would like to transform them and emit just two:

"records_updated", ids: [2], company_id: 2
"records_updated", ids: [6, 4], company_id: 3

Any hints on libraries/tools I could use to simplify this task? Should I be looking at GenStage/Broadway and implement this from scratch or there are some tools out there that do something similar to my requirements that you can recommend?

Most Liked

entone

entone

GenStage would probably work great for this use-case. GenStage — gen_stage v1.3.2

Broadway is built on top of GenStage, and could simplify a few things for you, but I think it definitely helps to have an understanding of the underlying concepts. Introduction — Broadway v1.3.0

hubertlepicki

hubertlepicki

I don’t think I want to use GenServers and buffer these events in memory. There’s several things i dislike about this approach: from the need to cluster process registration and sort of reconciliation to the fact that this is sort of wrong usage pattern as we’re using processes, which are runtime entities, to partition data, and all the ineffectiveness that this brings.

I am thinking now I’ll go with a PostgreSQL or Redis-based solution where I will in atomic way write the IDs of records that need to be broadcasted to clients as being updated, then have a recurring jobs on each node that will also in atomic way fetch and nullify the IDs and broadcast them to clients over PubSub.

hugobarauna

hugobarauna

Livebook Core Team

Maybe there’s something to learn from how Nx.Serving deals with batch size and batch timeout:

But yeah, it looks like something Broadway could help: Broadway — Broadway v1.3.0

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 130286 1222
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54006 488
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New

We're in Beta

About us Mission Statement