sagar_k317

sagar_k317

Hi! I am trying to build a solution and I need guidance as to what type of abstractions to use.

I have a pool of users and operators connected to my Phoenix app via channels. I have entries in my database for each operator and user along with their current state. Now I need to implement a basic FIFO queue of users. Whenever an operator’s state is ‘available’, I need to allocate the first member of the user queue to this operator and pop him out of the queue. The operator is now in a different state and will do some activities with this user through channels. The number of users can be less or more than the agents at any time.
I’d like to know if I should use an external library, like OPQ GitHub - fredwu/opq: Elixir queue! A simple, in-memory queue with worker pooling and rate limiting in Elixir. · GitHub, or implement Genstage on my own, or if there’s better solution to this entire problem.
Also, in order to make processing fast, I’m thinking of maintaining states of operators and users using Agent and then asynchronously update in the database.

Any sort of guidance will be really helpful.

Showing Posts 1 to 7

dimitarvp

dimitarvp

Have you looked at Oban?

Or Broadway?

axelson

axelson

Scenic Core Team

That’s an interesting problem statement. At first reading it seems like it might be good to model this with processes (using either GenServer or Agent). Can you explain more why you need to persist the operators state in the database? Could that instead be stored entirely in memory?

Based on my understanding of your description, OPQ doesn’t seem like a good fit because it simply has generic worker processes, whereas you need to assign users from the queue to a specific available operator.

I think what you primarily need is a FIFO queue of users, then whenever an operator becomes available, it can request the next user from the queue. That way the operators don’t need to talk to each other, instead they just need to pull items off of the shared queue. Depending on your scaling needs a single GenServer holding the queue of users should work fine (Look at the erlang queue module).

kokolegorille

kokolegorille

It’s not really a producer consumer problem, I think it’s more related to limited resource access (where operators are those limited resources)… In which case I would look for design like poolboy, with checkin/checkout.

There is Erlang :queue module to manage queue.

If You want to be fast, You shouldn’t think in terms of database. As mentionned by @axelson there are many ways to go faster than db. At most, I would use db to load state for a GenServer. When I really need speed, I reach for ETS.

I don’t think GenStage is a good fit, it’s more like a pipeline, with successive steps.

It looks like a call center model, or a helpdesk service.

There are similar ideas in voip asterisk server Asterisk Agents - VoIP-Info

sagar_k317

sagar_k317 OP

Thanks for the reply! Actually our business requires us to store various states in the Database because those will be used for deciding the billing and also analytics (I know for analytics we can use other approaches). The number of users can go upto 5000 at peak.

sagar_k317

sagar_k317 OP

Thank you! Looking into ETS :slight_smile:

sagar_k317

sagar_k317 OP

Oban too has generic workers which won’t fit in my use case.

xlphs

xlphs

Whenever an operator’s state is ‘available’, I need to allocate the first member of the user queue to this operator and pop him out of the queue.

Operator sounds like a Rabbitmq consumer that can only handle 1 task at a time, and user queue is Rabbitmq messages queued up under a certain topic (channel). This is more of a routing problem than consumer/producer problem. I don’t have any concrete implementation I can suggest but rabbitmq is open source so you could look at their code :thinking:

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews