-
-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace the polling in the webui with Websocket events #2422
Comments
This idea has been in my head for a long time, great that you want to tackle it.
I agree, I wonder what backend we want to use though, redis seem to be the obvious answer, but maybe we can leverage the existing services (rabbitmq/postgresl) instead of adding a new one. Or maybe we should simply add redis as it might be useful in the future anyway.
Sounds like a good idea. One problem we need to solve before doing this, is to properly handle authentication and authorization in django. Right now, we only allow read only access on some resources for the public, read only with the api key for internal communication and the read/write for the admin, but maybe @paddatrapper can correct me on this one, as we might support a bit more. In addition, we might have to authenticate twice (legacy + api) for any user using the UI, or setup a shared session store and only log in once. I would love to only log using the api and use a custom shared php session store for legacy #1788. Maybe we also use token based auth instead. |
I do not think we need redis, there is a backend for rabbitmq https://github.com/CJWorkbench/channels_rabbitmq |
The permission structure is based on the same groups as the UI - Guest, Host, Programme Manager and Admin. Specific permission handling isn't done for Admin, as they designated Django super admin access. The rest are defined in https://github.com/libretime/libretime/blob/main/api/libretime_api/permission_constants.py and https://github.com/libretime/libretime/blob/main/api/libretime_api/permissions.py |
I did some thinking and have a proposal on how to intgrate and couple channels into the django-app The rough idea idea is:
The channel will transport messages that are encoded as json. Client sideAfter connection client can send two events:
For troubleshooting the client will receive a response to either of these events:
Server sideAdd client to a groupWhen the server receives a "subscribe" message it will check if the Send notifications to a groupWe can overwrite the save/delete methods of the Django models.
We can either do this individually in every model, provide a class decorator or use a wrapper class that overrides the methods. Custom groupsThere could be custom groups that do not map to a django model. Permission checkingThe permission for a group is of form "view_modelname" for models or the specified one for the custom groups. Documentation and type generationThere should be a page in the docs that list all available groups and the data-format. I do not think they can be integrated into the openApi schema.yml There is https://www.asyncapi.com/ which seems it can do a similar thing for web-sockets. |
Is your feature request related to a problem?
The webui is using polling to update the data its showing.
E.g. the /Schedule/get-current-playlist/ endpoint is called ~5 sec. to check for changed playout information.
The Library and "Scheduled Shows" are also polling but on a much longer interval, which can lead to inconsistent views when multiple people (or tabs) are using Libretime simultaneously.
E.g. one is adding content to a show via the "Calendar" and the other one (not noticing, in his view the show is still empty) via the "Dashboard". This will result in duplicate content.
Describe the solution you'd like
I would like to add Websoket support to the Django-Api via channels.
I would like to have two sockets one "public" to which external clients can connect to get "now-playing" and "schedule-updates", and one "internal" for the webui to replace the polling.
I do not want to replace the existing REST-Api. I do think the Websockets only make sense for update notifications, not the initial loading/updating data. Also I think the REST-Api is easier to integrate to external tools.
I took a look through the webui and worked out the following events:
Metadata from the playout
When a show in the calendar gets updated/ deleted
When a Song/ Smartblock / Playlist / Track is added, changed or deleted
When the "Scheduled Shows" tab on the "Dashboard" should update
The events should contain the changed data for the webui to check if it should update.
The clients should be able to choose which events they want to receive.
Describe alternatives you've considered
An alternative to the Django-Channels would be to use RabbitMQ-websockets but then we would need to write cusom code to send the messages. Also I do not feel well exposing the RabbitMQ to the internet.
Also a Graphql endpoint could combine the "REST-Api" with an subscription feature for updates.
But as there is already a REST-Api I don't think we should have an additional api with "similar" features.
Also for the "subscription" the Django-Channels are needed to.
Additional context
The Websockets can only work for the items that are handled in the Django-Api so this should be added incrementally as the api gets migrated.
As a POC I would like to add the Websocket updates for the "live-info-changed" event as I think this is the easiest to implement in Django and webui.
I would appreciate to have some feedback for this idea :)
The text was updated successfully, but these errors were encountered: