DB/Device Supervision
DB Supervisor
DB Supervisor wraps every DB in Queue, Writer, Dry Status Relay, Decider and Compactor.
Queue and Writer are described in DB Prioritization.
Dry Status Relay is Agent that holds read-only state of DB. It is updated by Decider. And read by UI to show red indication.
Decider checks space left on device and starts writing or read-only configuration under WriteSupervisor. For write it starts Writer and Compactor. For read-only - DryWriter, which does no writes in DB or filesystem.
Compactor awaits for period of inactivity (7 minutes) and starts DB compaction. When Writer has something to write, it lets Compactor know, so compaction will get canceled if unfinished.
The supervision strategy is rest for one
. Which means that all peers to the right will get restated if children failed. I.e. if CubDB fails, Dry Status Relay, WriteSupervisor and Decider get restarted as well. Queue continues to work, aggregating all the changes User generated. This provides seamless switching into Read Only mode when there is no room to write data.
graph TD;
s(DB Supervisor)
s --> Queue
s --> db[(CubDB)]
s --> ds[Dry Status Relay]
s --> ws{{WriteSupervisor}}
s --> Decider
ws --> Compactor
ws --> Writer
ws -.-> DryWriter
This approach used in all DB Supervisors. Each handles its own DB, otherwise they are identical
-
Chat.Db.InternalDbSupervisor
-
Chat.Db.MainDbSupervisor
-
Chat.Db.MediaDbSupervisor
Device Supervision
Device managing happens in Platform
project. (It incorporates Chat
as dependency)
Here is a simplified supervision tree.
graph LR;
subgraph Chat
ids(InternalDbSupervisor)
mds(MainDbSupervisor)
meds(MediaDbSupervisor)
ca(Application)
ca -.-> ids
end
pa(Application)
ds(DeviceSupervisor)
cb[ChatBridge]
di[DriveIndication]
drive_sup{{Drives}}
dr[Drives.Registry]
udd[UsbDrives.Detector]
pa --> cb
pa --> di
pa --> ds
ds --> drive_sup
ds --> dr
ds --> udd
drive_sup -..-> mds
drive_sup -..-> meds
DriveIndication
handles extra LED indication hardware
ChatBridge
lets Chat to talk to Platform. Wifi setting and drives interaction are possible here.
UsbDrives.Detector
polls filesystem for USB devices plug/unplug.
Drives.Registry
registers processes used in drive dedicated subtrees.
Drives
- supervises detected drives. We need Dynamic Supervisors to start or shutdown supervision subtrees, since devices are not always present. Each drive gets its own subtree.
Drive subtree consists of 2 parts.
- Booting - heals filesystem, mounts it and decideces which scenario to run
- Scenario - supervises given scenario behavior
Depending on scenario, subtree will include MainDbSupervisor
or MediaSupervisor
to supervise DB.
graph TD;
ds{{Drives}}
bs(Boot)
dis[DriveIndicationStarter]
h[[Healer]]
healed{{Healed}}
m[[Mounter]]
mounted{{Mounted}}
sc{{Scenario}}
d[Decider]
ds -.-> bs
bs --> dis
bs --> healed
bs --> h
healed --> m
healed --> mounted
mounted --> sc
mounted --> d
DriveIndicationStarter
starts indication on custom hardware and ands it when drive ejected (i.e. this process terminated)
Healer
detects FS used on drive and checks FS w/ coresponding tool (FAT, exFAT or F2FS)
Mounter
mounts device into device dedicated folder
Decider
checks device content and starts according scenario under Scenario
supervisor.
Main drive supervision
graph TD;
pmds(Platform MainDbSupervisor)
mts(Task.Supervisor)
mm[[Mounter]]
mdt[DirTask]
mds(Chat MainDbSupervisor)
mb[[Bouncer]]
ms[[Starter]]
mc[[Copier]]
mr[[Replicator]]
msw[[Switcher]]
pmds --> mts
pmds --> mm
pmds --> mdt
pmds --> mds
pmds --> mb
pmds --> ms
pmds --> mc
pmds --> mr
pmds --> msw
Mounter
mounts device into folder specified. And unmounts when terminated.
DirTask
ensures that device filesystem has the folder to hold DB.
Chat MainDbSupervisor
is DB Supervisor from Chat
application described above.
Bouncer
prevents DB directory from being renamed.
Starter
changes global DB status (in application config). And reverts it back when terminated.
Copier
starts blinking leds and copies data. And finishing blinking when terminated.
Replicator
starts sync to internal DB every 5 mins. And stops when terminated.
Switcher
switches Current DB to main. And reverts Current DB back to internal when terminated.
Media drive supervision
graph TD;
pms(MediaSupervisor)
mets(Task.Supervisor)
mem[[Mounter]]
fds[FunctionalityDynamicSupervisor]
d[MediaDecider]
pms --> mets
pms --> mem
pms --> fds
pms --> d
pbds(Platform BackupDbSupervisor)
pcss(Platform CargoSyncSupervisor)
poss(Platform OnlinersSyncSupervisor)
fds ---> pbds
fds ---> pcss
fds ---> poss
bdt[DirTask]
bmds(Chat MediaDbSupervisor)
bb[[Bouncer]]
bs[[Starter]]
bc[[Copier]]
bst[[Stopper]]
pbds --> bdt
pbds --> bmds
pbds --> bb
pbds --> bs
pbds --> bc
pbds --> bst
csdt[DirTask]
csmds(Chat MediaDbSupervisor)
csb[[Bouncer]]
css[[Starter]]
cscds[[CargoDynamicSupervisor]]
csl[[Logic]]
csc[[Copier]]
csst[[Stopper]]
pcss --> csdt
pcss --> csmds
pcss --> csb
pcss --> css
pcss --> cscds
pcss --> csl
cscds --> csc
cscds --> csst
osdt[DirTask]
osmds(Chat MediaDbSupervisor)
osb[[Bouncer]]
oss[[Starter]]
osods[[OnlinersDynamicSupervisor]]
osl[[Logic]]
osc[[Copier]]
osst[[Stopper]]
poss --> osdt
poss --> osmds
poss --> osb
poss --> oss
poss --> osods
poss --> osl
osods --> osc
osods --> osst
Mounter
mounts device into folder specified. And unmounts when terminated.
Decider
figures out which functionality to start under FunctionalityDynamicSupervisor
.
It does it by checking whether device contains appropriate directory (backup_db
for backup, cargo_db
for cargo, or onliners_db
for onliners sync).
If not, it checks the media settings in the Chat Admin room.
If it’s not set yet, the default functionality is used (backup).
Some of the modules are reused between the functionalities. We’ll describe them here while the unique aspects of the functionalities will be described in the below sections.
DirTask
ensures that device filesystem has the folder to hold DB.
Chat MediaDbSupervisor
is DB Supervisor from Chat
application described above.
Bouncer
prevents DB directory from being renamed.
Starter
changes global DB status (in application config). And reverts it back when terminated.
Copier
starts blinking leds and copies data. And finishing blinking when terminated.
Stopper
starts extra LED blinking and makes Platform MediaSupervisor
to stop. On termination stops LED blinking.
Platform BackupDbSupervisor
Synchronizes MainDb and BackupDb by copying the data that’s available on the device, but not in the MainDb and vice versa.
Platform CargoDbSupervisor
Copies data from the Cargo room. If there’s some data on the device, it copies it to the main drive. Otherwise, it copies data from the only room on main drive. If the room doesn’t exist yet, or if there are multiple rooms, it skips copying data.
Logic
is responsible for deciding which room is for Cargo, then starts Copier
and Stopper
under
CargoDynamicSupervisor
.
Platform OnlinersSyncSupervisor
Backs data up for the online users. If there’s some data data on the device, it restores it, but again only for the online users. Accomplishes this by sending a request for the keys to each online users’ LiveView process. After receiving keys for all online users and their rooms, it gathers the content on the device belonging to them and copies it from the device, then gathers the content in the MainDb and copies it to the device.
Logic
is responsible for sending and receiving PubSub requests, getting the keys for
the content that needs to be copied both from and to BackupDb, and starting
Copier
and Stopper
under OnlinersDynamicSupervisor
.