diff --git a/docs/developer-manual/README.md b/docs/developer-manual/README.md index eccb1f3d3..2ad2cf809 100644 --- a/docs/developer-manual/README.md +++ b/docs/developer-manual/README.md @@ -10,4 +10,4 @@ Welcome to the **LibreTime developer manual**, you should find guides to integra ## Improve and contribute to LibreTime -- :construction: Work in progress +- Learn about the [architecture of LibreTime](./design/architecture.md) diff --git a/docs/developer-manual/design/_category_.yml b/docs/developer-manual/design/_category_.yml new file mode 100644 index 000000000..7c5227276 --- /dev/null +++ b/docs/developer-manual/design/_category_.yml @@ -0,0 +1 @@ +label: Design diff --git a/docs/developer-manual/design/architecture.md b/docs/developer-manual/design/architecture.md new file mode 100644 index 000000000..980cdcfe5 --- /dev/null +++ b/docs/developer-manual/design/architecture.md @@ -0,0 +1,108 @@ +--- +title: Architecture +--- + +This document explains the design details and goals for the architecture of LibreTime. It describes the result of a [discussion that happened on Github](https://github.com/libretime/libretime/issues/1610). + +## Previous architecture + +The previous architecture of LibreTime (based on AirTime) was missing a proper separation of concerns. It was build around a legacy MVC app written in PHP, and services in Python to accomplish specific tasks. + +## New architecture + +Below is the new architecture goal of LibreTime, with a proper separation of concerns. + +```mermaid +flowchart TD + users([Users]) + public([Public]) + + subgraph create_schedule[Create the schedule] + webapp[Web app] + subgraph core[Backend] + message_api[Message API] + api[Web API] + worker[Worker] + end + end + + subgraph play_schedule[Play the schedule] + playout[Playout] + liquidsoap[[Liquidsoap]] + icecast[[Icecast]] + hls[[HLS]] + end + + message_queue[[Message Queue]] + database[[Database]] + storage[[Storage]] + + users --> |Edit| webapp + + webapp --> api + api --> database + api --> storage + api --> message_queue + + message_queue <--> worker + worker --> database + worker --> storage + + message_queue <--> message_api + message_api --> database + + message_queue <--> playout + playout <-. via message queue .-> message_api + playout --> |e.g. download file| api + playout <--> liquidsoap + liquidsoap --> icecast + liquidsoap --> hls + + public --> webapp + public --> |Listen| icecast + public --> |Listen| hls +``` + +The LibreTime architecture is split into 2 main monolithic blocks `Create the schedule` and `Play the schedule`. Both blocks must be able to scale horizontally. + +:::note + +A microservice architecture was rejected as it will not fix or improve any aspect of LibreTime. + +::: + +:::warning + +This document tries to focus on creating and playing a schedule, it does not consider features such as monitoring, logging or archiving. + +::: + +### Create the schedule + +This block contains the following components: + +- a web API, +- a worker to run background tasks, +- a message API to communicate with the `Play the schedule` block, and other services, +- a web app to interface with the users. + +The web API, the worker and the message API rely on the [Django framework](https://www.djangoproject.com/) to handle database, message queue and storage access. + +### Play the schedule + +Since the `Play the schedule` has its own requirements in terms of logic and uptime, it is handled separately from the `Create the schedule` block. This block needs to be able to be duplicated in a high availability context. + +This block contains the following components: + +- a Playout app that communicates with the `Play the schedule` block to gather the schedule, +- a Liquisoap app that plays and mixes the scheduled items, and dispatch them to the delivery services, +- an Icecast server that delivers a legacy audio stream to the public, +- a HLS stream that delivers a modern audio stream to the public. + +### One setup per radio station + +LibreTime is not meant to be used in a multi-tenant architecture, and an entire LibreTime installation should be dedicated to a single radio station. Previous SAAS or multi-tenant features from Airtime should be deprecated or removed. + +### Separation of concerns + +The `Create the schedule` block must only prepare a schedule, and the `Play the schedule` must only play that schedule. A strong separation of concerns is required between the 2 blocks to allow the `Play the schedule` block to meet its uptime requirements while not depending on the `Create the schedule` in case of a failure. Development will be simplified if both blocks share a single and properly defined protocol.