Skip to content

Race condition between WebSocket and /api/settings #2075

@RobertSasak

Description

@RobertSasak

System OS

MacOS

Python Version

3.7 (CPython)

Install Source

pip / PyPi

Install version / commit hash

4.2.5

Expected Behavior vs Actual Behavior

Thank you for a great tool! 🔨♥️

I experience a race condition in web UI. There are two request that are fired from JS. One is a WebSocket connection and the other one is a GET call to retrieve settings.

WebSocket Connection have to be first and creates an client with a specific cliend_id. Afterwards a call to fetch settings can be made.

If this happen in opposite order the settings call receice a 404 error. This will cause the settings object to not defined. If it the web app is used in this state this leads to malforming settings. Any changes to settings will override any settings that were originally set on server. Especially output setting.

Here are two screenshost.

First screenshot is a correct order of calls. Notice that WebSocket is before settings call.
Screenshot 2024-04-26 at 12 16 31

Here occurs an error. Notice that WebSocket is openning after settings call.
Screenshot 2024-04-26 at 12 15 56

Steps to reproduce - Ensure to include actual links!

  1. Run spotdl web
  2. Wait until web UI is openned
  3. Open Chrome inspect panel and switch to network
  4. Notice that request to /api/setttings?cliend_id=ABC... fail with error 404
{"detail":"client not found"}

This does not happen all the time. Keep refreshing browser until error happens.

Traceback

Updating web app                                                                                                                               
                                                                                                                                               
Files are stored in temporary directory and will be deleted after the program exits to save them to current directory permanently enable the   
`web_use_output_dir` option                                                                                                                    
Starting web server                                                                                                                            
                                                                                                                                               
INFO:     Started server process [75376]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://localhost:8800 (Press CTRL+C to quit)
INFO:     ::1:52099 - "GET / HTTP/1.1" 200 OK
INFO:     ::1:52099 - "GET /assets/index-CGxZV3ZT.js HTTP/1.1" 200 OK
INFO:     ::1:52100 - "GET /assets/index-BDDgGyM9.css HTTP/1.1" 200 OK
INFO:     ::1:52100 - "GET /api/version HTTP/1.1" 200 OK
INFO:     ('::1', 52101) - "WebSocket /api/ws?client_id=a86f158b-1995-47b5-a7c0-6828ca47756a" [accepted]
INFO:     Client a86f158b-1995-47b5-a7c0-6828ca47756a connected
INFO:     connection open
INFO:     ::1:52099 - "GET /api/settings?client_id=a86f158b-1995-47b5-a7c0-6828ca47756a HTTP/1.1" 200 OK
INFO:     ::1:52100 - "GET / HTTP/1.1" 304 Not Modified
INFO:     connection closed
INFO:     ::1:52100 - "GET /assets/index-CGxZV3ZT.js HTTP/1.1" 304 Not Modified
INFO:     ::1:52099 - "GET /assets/index-BDDgGyM9.css HTTP/1.1" 304 Not Modified
INFO:     ('::1', 52112) - "WebSocket /api/ws?client_id=8aff6d6e-d397-4e15-a4e7-e33b530c63d7" [accepted]
INFO:     Client 8aff6d6e-d397-4e15-a4e7-e33b530c63d7 connected
INFO:     connection open
INFO:     ::1:52099 - "GET /api/version HTTP/1.1" 200 OK
INFO:     ::1:52100 - "GET /api/settings?client_id=8aff6d6e-d397-4e15-a4e7-e33b530c63d7 HTTP/1.1" 200 OK
INFO:     ::1:52114 - "GET /favicon.ico HTTP/1.1" 200 OK
INFO:     ::1:52144 - "GET /assets/index-BDDgGyM9.css HTTP/1.1" 304 Not Modified
INFO:     ::1:52144 - "GET / HTTP/1.1" 200 OK
INFO:     connection closed
INFO:     ::1:52144 - "GET /assets/index-CGxZV3ZT.js HTTP/1.1" 200 OK
INFO:     ::1:52149 - "GET /assets/index-BDDgGyM9.css HTTP/1.1" 200 OK
ERROR:    Client d7e335c6-070d-499b-aff1-a65d8fbecfba not found
INFO:     ::1:52144 - "GET /api/version HTTP/1.1" 200 OK
INFO:     ::1:52149 - "GET /api/settings?client_id=d7e335c6-070d-499b-aff1-a65d8fbecfba HTTP/1.1" 404 Not Found
INFO:     ('::1', 52150) - "WebSocket /api/ws?client_id=d7e335c6-070d-499b-aff1-a65d8fbecfba" [accepted]
INFO:     Client d7e335c6-070d-499b-aff1-a65d8fbecfba connected
INFO:     connection open
INFO:     ::1:52149 - "GET /favicon.ico HTTP/1.1" 200 OK

Other details

Propose fix

Wait with bootstrapping a Vue app after the WebSocket connection is alive.
https://github.com/spotDL/web-ui/blob/master/src/model/api.js#L19-L26

Perhaps the whole app can be wrapped in a loading component which renders loading while WebSocket is initializing and only once it is ready to render whole app.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugUnexpected problem or unintended behavior that needs to be fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions