Building a a tree of general and dynamic supervisors


Ununtu 18.04
Elixir 1.9.4
Compiled with Erlang/OTP 21

I’m building a ride share simulator that currently only logs to a file. My goal is to eventually build a web app to allow watching a live view of the system and the past. That’s a discussion for another time.

It starts an initial Supervisor to manage the city (:a in this post)… Which then spawns DynamicSupervisors, Managers (just logic holding GenServers), and Workers (N number of individual GenServers).

The structure of a city is based on: zones (geo-fenced neighborhoods), drivers (arbitrary number passed in when the sim is started), and riders (arbitrary number pasted in when the sim is started).

I’ve learned the basics of the language and worked through the Little OTP book. I’m probably over complicating this but it’s an elixir learning exercise at this point. I really want to deeply understand how to build and manage a supervision tree in the current version that has layers of Supervisors. One layer would have a defined number of children (Supervisors), DynamicSupervisors and generic GenServers for logic. The Dynamic Supervisors would be told to spawn children from GenServers when needed.

The process is:

  • Start Application
  • Application starts a CitySupervisor
  • CitySupervisor starts a CityManager, ZonerSupervisor, DriverSupervisor and a RiderSupervisor
  • ZoneSupervisor starts a ZoneManager (just a logic server) and zones (neighborhoods)
  • DriverSupervisor starts a DriverManager (just a logic server) and individual driver nodes
  • RiderSupervisor starts a RiderManager (just a logic server) and individual rider nodes

Been trying to start a supervision tree. Basic structure:

    |     |            |            |
   :b    :c           :d           :e   
          |            |            |
       -------      -------      -------
       |     |      |     |      |     |
      :f  :g...n   :h  :i...n   :j  :k...n   	  

:a - CitySupervisor: Starts the supervision tree

:b - CityServer: Has all high level city related functions that get called after city init
:c - ZoneSupervisor: Neighborhood geo-fences
:d - DriverSupervisor
:e - RiderSupervisor

:f - ZoneServer: Server that does all the work of checking all drivers in/out of zones
:g - DriverServer: Server that manages communication to riders, the ZoneServer (keeps the state of who is in what zone) and also talks to a GraphHopper Server (network api call) to retrieve route planning planning data
:h - RiderSupervisor: Server that manages communication to drivers

:g…n - The geo-fenced neighborhood zones in a city
:i…n - N number of drivers active in the city
:k…n - N number of riders requesting rides in the city

I’ve got a bunch of ugly old code I’m still parsing through. I just really need to know how to appropriately start :a as a general Supervisor that manages a GenServer and 1+ DynamicSupervisors. Then each DynamicSupervisor to manage a GenServer who can start other Dynamic or not Supervisors or GenServers.

Thanks for your time.

These all look reasonable. I might split the Rider, Driver, Zone into individual applications and have the City application which manages the rest. I might do this split if you find Rider, Driver, Zone getting large from business logic.