Hello,
I need some guidance to create an “exclusive” 1 to 1 chat.
By “exclusive” it means that at anytime an user can only chat with one person and one person only.
Basically the the idea is the following:
- To chat with someone, a user must first do a request to another user.
What is a request ?
It would be a yes/no question “do you accept to chat with x ?” that a user receives, and has a limited amount of time (1 minute) to accept. After that time, a user would have to send another request, if he desires to engage in a discussion with that person.
-
A user can send multiple chat requests at the same time to different users.
-
While a user is sending requests, he can also receive requests from other users.
-
When a user accepts a user request, 2 things should happen:
-
The other users he has sent requests to, or users who sent him request, should be told that he has chosen to discuss with someone else.
-
No one can send request to him anymore, unless the user he’s chatting with, decided to leave the channel.
So let’s say we have 4 players: Riri, Fifi, Loulou and Donald.
We would have one channel for each player and the topic would be “user:dicussion:#userid”
Scenario:
-
Riri sends a request to Fifi and Loulou
-
When it’s confirmed the message was received by a user, a countdown starts on both sides.
-
In the middle of this, Donald sends a request to Riri => Another countdown starts
-
At this stage, Riri could either accept Donald’s request or Fifi and/or Loulou might accept.
-
Either way, if Riri accepts Donald’s request and at the same time Fifi and Loulou also do, the challenge (at least to me) is to find the fastest.
As said previously, we don’t want to create 3 conversations but only one with the fastest positive answer and reject the others.
2 scenarios :
-
If Riri accepted Donald’s request before Fifi or Loulou accepted, the discussion should start between Riri and Donald, while Fifi and Loulou should be told Riri found someone else.
-
If Loulou was faster to accept than Riri, it should be the other way round.
Bearing in mind the backend API will be a blue-green clustered deployment, it could be different nodes that deal with the messages in the same channel, so the question is how do I keep track of the fastest user to accept a request ?
My initial idea is to push the users’s acceptance to a queue, so that they get treated one after the other.
If we go back to the first scenario:
-
Riri accepts Donald’s request
-
Riri’s acceptance is pushed to the queue
-
Loulou accepts riri’s request
-
Loulou’s acceptance is pushed to the queue
-
In the queue, we check each acceptance message using what’s stored in the DB
-
When we find the fastest, we update the DB, we notify the fastest user, and the other users unsuccessful with rejection answer.
Is there anything better we can do and if not, would it still remain scalable whatever the number of users and requests ?
The other thing is to prevent a user from sending a request to the that topic, if the acceptance already occurred. Bearing in mind, the backend API will be clustered, how is it possible to know in real time time how many users are in the channel on all nodes ?
Please note that I’m still in the process of learning Phoenix. I’ve been a nodeJS dev for many years before recently making the switch to Elixir.
Cheers,