diff --git a/figures/full-package-diagram.puml b/figures/full-package-diagram.puml index a25307b..82be0e9 100644 --- a/figures/full-package-diagram.puml +++ b/figures/full-package-diagram.puml @@ -42,39 +42,43 @@ folder "Nodejs packages" { ] package ott_vis [ - Common code shared between visualization grafana plugins + Common code shared between + visualization grafana plugins ] package ott_vis_panel [ - Grafana Panel plugin for custom visualizations + Grafana Panel plugin + for custom visualizations ] package ott_vis_datasource [ - Grafana Datasource plugin for querying system state + Grafana Datasource plugin + for querying system state ] } -ott_balancer --> ott_common_rust : depends -ott_balancer -> ott_balancer_protocol : depends +ott_balancer --u> ott_common_rust : depends +ott_balancer -r> ott_balancer_protocol : depends harness --> ott_balancer_protocol : depends harness_tests --> harness : depends harness_tests -> ott_balancer_protocol : depends harness <..> ott_balancer : connects via websockets -ott_server ...> ott_balancer_bin : connects via websockets +ott_server ..[norank]> ott_balancer_bin : connects via websockets ott_client ..> ott_server : connects via websockets -ott_balancer_bin --> ott_balancer : depends +ott_balancer_bin --u> ott_balancer : depends -ott_server -> ott_common : depends -ott_client --> ott_common : depends +ott_server --> ott_common : depends +ott_client --u> ott_common : depends ott_vis_panel --> ott_vis : depends -ott_vis_datasource --> ott_vis : depends -ott_vis_panel ..> ott_vis_datasource : queries -ott_vis_datasource ..> ott_collector : queries +ott_vis_datasource --d> ott_vis : depends +ott_vis_panel ..u> ott_vis_datasource : queries +ott_vis_datasource ..[norank]> ott_collector : queries ott_collector ..> ott_balancer_bin : queries ott_collector --> ott_common_rust : depends -"Nodejs packages" -[hidden]d- "Rust crates" +' positioning hacks +ott_vis -[hidden]d- ott_client @enduml diff --git a/figures/full-package-diagram.svg b/figures/full-package-diagram.svg index a8afc07..52efb58 100644 --- a/figures/full-package-diagram.svg +++ b/figures/full-package-diagram.svg @@ -1 +1 @@ -Rust cratesNodejs packagesott_common_rustContains common functionalityott_balancer_protocolProvides types shared betweenthe Balancer and MonolithharnessProvides abstraction aroundintegration testing the Balancerott_balancerThe Balancerott_balancer_binThe Balancer (builds as a binary)harness_testsTests the Balancer using harnessott_collectorCollects system state for visualizationott_commonCommon types and functionalityshared between ott_server and ott_clientott_serverThe Monolithott_clientThe web clientott_visCommon code shared between visualization grafana pluginsott_vis_panelGrafana Panel plugin for custom visualizationsott_vis_datasourceGrafana Datasource plugin for querying system statedependsdependsdependsdependsdependsconnects via websocketsconnects via websocketsconnects via websocketsdependsdependsdependsdependsdependsqueriesqueriesqueriesdepends \ No newline at end of file +Rust cratesNodejs packagesott_common_rustContains common functionalityott_balancer_protocolProvides types shared betweenthe Balancer and MonolithharnessProvides abstraction aroundintegration testing the Balancerott_balancerThe Balancerott_balancer_binThe Balancer (builds as a binary)harness_testsTests the Balancer using harnessott_collectorCollects system state for visualizationott_commonCommon types and functionalityshared between ott_server and ott_clientott_serverThe Monolithott_clientThe web clientott_visCommon code shared betweenvisualization grafana pluginsott_vis_panelGrafana Panel pluginfor custom visualizationsott_vis_datasourceGrafana Datasource pluginfor querying system statedependsdependsdependsdependsdependsconnects via websocketsconnects via websocketsconnects via websocketsdependsdependsdependsdependsdependsqueriesqueriesqueriesdepends \ No newline at end of file diff --git a/glossary.yaml b/glossary.yaml index 4ced050..a06b63c 100644 --- a/glossary.yaml +++ b/glossary.yaml @@ -6,7 +6,13 @@ Client: link: https://github.com/dyc3/opentogethertube/tree/master/client Balancer: definition: The load balancer for OTT. - link: https://github.com/dyc3/opentogethertube/tree/master/crates + link: https://github.com/dyc3/opentogethertube/tree/master/crates/ott-balancer +Collector: + definition: Used by the visualizations to collect state information and activity from the Balancers. + link: https://github.com/dyc3/opentogethertube/tree/master/crates/ott-collector +OpenTogetherTube: + definition: Open source video synchronization software where users can join a room and watch videos added to a queue with other users in the same room + link: https://opentogethertube.com/ OTT: definition: OpenTogetherTube, the name of the project. link: https://github.com/dyc3/opentogethertube @@ -22,6 +28,3 @@ Redis: link: https://redis.io Harness: definition: The integration testing tool that is used to test the balancer. -OpenTogetherTube: - definition: Open source video synchronization software where users can join a room and watch videos added to a queue with other users in the same room - link: https://opentogethertube.com/ diff --git a/join-process.typ b/join-process.typ index 3ed1acc..36caf8c 100644 --- a/join-process.typ +++ b/join-process.typ @@ -42,7 +42,7 @@ Monoliths must gossip: The gossip message must contain a list of rooms that the Monolith is hosting (@Figure::gossip-class-diag). To save on bandwidth, when a room is loaded or unloaded, only information about that room is sent to the Balancer in the form of "load" and "unload" messages. #figure( - image("figures/gossip-class-diag.svg", width: 20%), + image("figures/gossip-class-diag.svg", width: 200pt), caption: "Simplified gossip class diagram." ) @@ -56,19 +56,19 @@ Room generation requires no inputs from the client, instead a new uuid is automa #figure( image("figures/create-room-diag.svg"), - caption: "Creating or generating a new room." + caption: "Sequence diagram for creating or generating a new room." ) === Lifetime of a Room -Rooms are only kept loaded in memory if there are clients that are connected to them. If a room is loaded and there are no clients connected, it will be unloaded after a certain amount of time. +Rooms are only kept loaded in memory if there are clients that are connected to them. If a room is loaded and there are no clients connected, it will be unloaded after a certain amount of time (@Figure::room-keepalive-timing). #figure( image("figures/room-keepalive-timing.svg"), caption: "A timing diagram describing the lifetime of a loaded Room in a Monolith's memory." ) -=== Monolith Node Selection +=== Monolith Selection The Balancer must be able to select the Monolith that is most appropriate to handle the join. Specifically: @@ -77,7 +77,7 @@ The Balancer must be able to select the Monolith that is most appropriate to han == Joining an Unloaded Room When a user tries to join a permanent room in OpenTogetherTube, the request is first received by the Balancer. -The Balancer forwards the request to one of the available Monoliths based on the current load balancing algorithm (See @Section::MonolithNodeSelection). +The Balancer forwards the request to one of the available Monoliths based on the current load balancing algorithm (See @Section::MonolithSelection). This process is shown in @Figure::unloaded-room. #figure( diff --git a/visualization-design.typ b/visualization-design.typ index bf9f34e..1dc9653 100644 --- a/visualization-design.typ +++ b/visualization-design.typ @@ -110,20 +110,18 @@ client = { The load balancer is one part of a distributed system, and many instances of the Balancer can be active simultaneously. One instance of the visualization should have the capability of receiving information from multiple Balancers, and should do so in real time. Additionally, the visualization should have the capability of receiving data from both the official deployment of OTT on fly.io and self-hosted instances. -Grafana supports querying Prometheus, and there is documentation linked below on a quick start for creating a new data source. Given the Balancer has already integrated Prometheus for metrics, this is the preferred method for gathering data. There is no mention on compatibility with D3.js, but assuming there are no issues integrating D3.js into a Grafana panel, this should not be a problem. #cite() +Grafana supports querying Prometheus, and supports custom data sources through its plugin system. Given the Balancer has already integrated Prometheus for metrics, this is the preferred method for gathering data. #cite() Grafana is a tool primarily meant for time series data, and no current data source plugins support receiving the type of information needed. To add support, a custom data source must be created. -== Receiving Information From Load Balancers - -Grafana is a tool primarily meant for time series data, and no current data source plugins support receiving the type of information needed. To add support a custom data source must be created. +The Collector will be responsible for querying the Balancer for the data needed to display the visualization. === Balancer Discovery -While the visualization is running: Multiple instances of the Balancer can be active simultaneously, new instances can become active, and instances can go offline. The addresses of these Balancers are not known at runtime, so a discovery process similar to @Chapter::ServiceDiscovery must run to collect data from the discovered Balancers. - -In order to achieve this, a new rust crate will be created to handle this discovery process. Implementation will likely be similar to @Chapter::ServiceDiscovery. A port will be opened to listen for active instances of the Balancer. When a connection or connections are found, the Balancer discoverer clones the Balancer(s) and connects. +While the visualization is running, multiple instances of the Balancer can be active simultaneously, new instances can become active, and instances can go offline. The network addresses of these Balancers are not known at runtime, so the Collector must perform service discovery (as described in @Chapter::ServiceDiscovery). It must run as a prerequisite in order to collect data from the Balancers. === Querying Balancers +After the Collector has discovered the Balancers, it must query them for the data needed to display the visualization. The data source will then query the Collector for the data. + #figure( image("figures/vis/visualization-balancer-datasource-sequence.svg"), caption: "Sequence Diagram Explaining How Grafana Receives Data From Load Balancers" @@ -175,11 +173,15 @@ There are 4 components that need to be running in order to have the visualizatio See @Section::dev-env for instructions on running the Monolith with the Balancer. -The easiest way to do this is with the `with-balancer.docker-compose.yml` file. This file will run the balancer, monolith, and collector in a docker-compose environment. +#block(breakable: false)[ + The easiest way to do this is with the `with-balancer.docker-compose.yml` file. This file will run the balancer, monolith, and collector in a docker-compose environment. -#text-box( - raw("docker-compose -f docker/with-balancer.docker-compose.yml up -d") -) + #text-box([ + ```bash + docker-compose -f docker/with-balancer.docker-compose.yml up -d + ``` + ]) +] #let vis-dev-env-figure(path, caption, balancer-config, collector-config, commands) = { figure( @@ -236,6 +238,7 @@ Alternatively, @Figure::vis-dev-env-no-docker shows how to run the balancer, mon read("data/dev-env/commands-vis-no-docker.txt"), ) +#block(breakable: false)[ === Checklist - Ensure Grafana is accessible at #link("http://localhost:3500") @@ -246,3 +249,4 @@ Alternatively, @Figure::vis-dev-env-no-docker shows how to run the balancer, mon - Make sure load balancing is enabled - Ensure the collector is running and accessible at #link("http://localhost:8000") - Make sure the collector is configured with the balancer's api key +]