favetelinguis

favetelinguis

Need help with architecture for a tricky connection scenario

Im currently working on a hobby project for writing an Elixir integration for Betfair (odds exchange trading, sort of the same as any trading your can place orders via REST and you get push data from market and any order changes). To integrate with betfair two techniques are used. First there is a REST interface and secondly there is a TCP connection for streaming market and order data. Below I will describe the general requirements for the integration.

The first thing is to call a REST endpoint supplying username and password to login, this login starts a session on Betfair and returns a session token that needs to be included as a header for all future REST calls.
The session token is valid for 4hours, after 4hours a keep alive REST call needs to be done to extend the session for another 4hours.

Next one makes a REST call to get back a number of market ids. The list of market ids AND the session token are then supplied to a TCP connection to start a subscription and get market updates. Another subscription can be made on the same TCP connection or on another TCP connection for order updates.

The TCP connection receives akeep alive signal every 5seconds from the server, if no signal arrives within 5 seconds one has to re-subscribe using the same market ids and session token.

If either a REST call or the TCP connection return a invalid session reply one has to re-login to get a new session token and then re-subscribe with the same market ids but with this new session token.

Once I have logged in and started a subscription all the handling of the connection should be done automatically without any human intervention.

I have manage to get everything working by using two instances of Connection library, one for the REST interface keeping the session token and the keep alive process, and a second Connection for both Order and Market stream. However the implementation is just a big pile of mud and I would really love input on how more experienced Elixir developers would structure the code.

The type of questions I would like input on are:

  • How many processes would you use?

  • How would your supervisor tree look like?

  • What would be the responsibility of each process?

Most Liked

christophermlne

christophermlne

I might try something like this:

christophermlne

christophermlne

Yes sorry – because this is my first post I got stuck in some sort of moderation queue. I had originally intended to post the image and then edit the post to fill in the details

Please note also that I am not an expert in OTP although I have built some things with it.

To answer your question, you should design the supervision tree so that parts of the system that are invalid without each other crash together. So, if the SessionManager sends that request after the 4th hour and something goes wrong, it should die and take the SubscriptionManager down with it. The ApiSupervisor would then respawn a new SessionManager and SubscriptionsManager.

When the SessionManager is (re)started, it should make the POST request and get back the auth token (and keep it in its own gen_server state). As part of init, you can schedule the re-validation of the session with Process.send_after and give it a delay of just under 4 hrs. Other processes that need the session info, such as the SubscriptionWorkers can request it by sending the SessionManager a message which the SessionManager knows how to respond to (eg something like def handle_call(:get_session_info, args) ).

The SessionManager should tell the SubscriptionsManager when it is ok to spawn the SubscriptionWorkers after it has acquired valid session data. The SubscriptionsManager should therefore be a DynamicSupervisor.

I add a Store process because you may want your SubscriptionWorkers to keep their data in a different supervision tree. The Server process handles requests from the outside world and responds with data from the Store. Actually, you should place the server under a supervisor so that when it crashes it doesn’t wipe out the data in the store.

If either of the SubscriptionWorkers messes up its TCP connection, they should terminate with a specific message that causes their supervisor to crash (because the session will have become invalid)

Where Next?

Popular in Questions Top

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
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New

Other popular topics Top

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
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New

We're in Beta

About us Mission Statement