simon

simon

General Architectural Advice For A Ported Application

I’m looking for some general, high-level architectural advice and opinions because I want to port a system over to Elixir which is currently written in Node (data processing server) and the meteor JavaScript framework (web interface). Sorry that this is such a long post!

I have a number of devices which send data to a server via TCP. We also have data coming in over HTTP which comes from things like an SMS service, webhooks from MailGun, etc. Incoming data is stored in a database after it has been validated and processed. At the moment this is all done on servers running Node.

There is also a web application which allows users to log in and view data as well as allowing administrative users to set up and manage devices, etc. This is currently a Meteor-based system.

We also have a basic API so that an iOS app can interact with the system and the API is part of the Meteor application (it was 50/50 as to whether it should be part of the Node system but credential authentication was easier if it was part of the Meteor application).

In Elixir I think that I will need the following but this is where I need some advice before I head too far down the wrong path:

  • A database application which is an Ecto ‘layer’. It will contain schemas and data management functions and essentially be an API for everything else to use to centralise database access.
  • An Absinthe GraphQL application which will be used to allow external systems to interact with the system. For example, the iOS application will use this as and we could also allow third parties to use it to retrieve data for reporting purposes, etc.
  • An incoming data application which will use Cowboy to handle HTTP data for things like the incoming SMS data and webhooks.
  • Incoming data applications which will use Ranch to create TCP servers for incoming device data. Rather than having a single server as I did i the Node application it would make life easier to have several of these, one per device type so that I can simplify parsing data from different device types rather than having to determine the type of incoming data first and then parsing it accordingly.
  • A Phoenix application which will be the web application for viewing data, managing devices, etc.

I’m sure that some of these could be rationalised and merged (a single Phoenix application could, I think, encapsulate Ecto, Absinthe and the Cowboy functionality) but I want to be able to scale functional areas separately. In the current system, mainly for redundancy, we have two servers running the Node data processing code which sit behind a load balancer and we have two servers running the Meteor application, again sitting behind a load balancer. We have separated the data processing from the web application because the volume of devices reporting in will always grow much faster than the number of operators using the web application so we want to be able to add more data processing servers without having the overhead of having to add more web application servers.

At the moment my thoughts are to have incoming data processing handled on a server which runs an application which supervises an instance of the Cowboy application and instances of the Ranch applications The Cowboy application and the Ranch applications would all use the Ecto application for database access.

The web application server would be a Phoenix application which use the Ecto application for database access.

The API application server would be an Absinthe application which also uses the Ecto application for database access. I’d like to separate this from the Phoenix application, again for scalability but also so that if the Phoenix server(s) went down there would still be access via the iOS app (and vice versa). Am I right in thinking that Absinthe doesn’t need Phoenix and can use Plug instead?

Does that all sound reasonable or is there a better way to structure things?

Can I separate my Ecto application from Phoenix and Absinthe in the way I’m thinking I can?

I really just want to be as sure as I can that I’m not starting off down the wrong path.

Most Liked

simon

simon

To help others who might find it useful, my searching skills were obviously lacking because I’ve just come across another forum post about this sort of thing which gives some great advice and opinions.

Where Next?

Popular in Questions Top

Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
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
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
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
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement