Store each client's play queue in the database
The queue lived in memory and was shared by all clients, so a restart or a finished sync cleared it. Every client now has its own queue in the new queue and queue_song tables (added to the undeployed migration 000006). The music endpoints return the queue ID in the X-Queue-Id header and expect it back. A request without an ID, or with an ended one, starts a new queue. /music/reset ends the queue and returns a new ID, and a sync ends all running queues. Ended queues are kept as history. The deprecated legacy routes without the /api/v1 prefix are removed.
This commit is contained in:
1 parent
b5dc42b654
commit
a705d7b476
28 files changed
+1103
-320
No files matched your search
@@ -1,10 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import "github.com/danielgtaylor/huma/v2"
|
||||
|
||||
// Deprecation marks responses from legacy routes as deprecated in favour of /api/v1.
|
||||
func Deprecation(ctx huma.Context, next func(huma.Context)) {
|
||||
ctx.AppendHeader("Warning", `299 - "Deprecated: This endpoint is deprecated. Use /api/v1/ endpoints instead."`)
|
||||
ctx.AppendHeader("Deprecation", "true")
|
||||
next(ctx)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"music-server/internal/logging"
|
||||
|
||||
"github.com/danielgtaylor/huma/v2"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// QueueHeader carries the client's queue ID in requests and responses.
|
||||
const QueueHeader = "X-Queue-Id"
|
||||
|
||||
type queueKey struct{}
|
||||
|
||||
// QueueID returns the queue ID resolved by Queue.
|
||||
func QueueID(ctx context.Context) uuid.UUID {
|
||||
id, _ := ctx.Value(queueKey{}).(uuid.UUID)
|
||||
return id
|
||||
}
|
||||
|
||||
// Queue resolves the queue ID in the X-Queue-Id header with resolve, which starts a new queue
|
||||
// when the header is missing or the queue has ended. The ID is returned in the same header.
|
||||
func Queue(api huma.API, resolve func(context.Context, string) (uuid.UUID, error)) Middleware {
|
||||
return func(ctx huma.Context, next func(huma.Context)) {
|
||||
id, err := resolve(ctx.Context(), ctx.Header(QueueHeader))
|
||||
if err != nil {
|
||||
logging.GetLogger().Error("Failed to resolve queue", zap.Error(err))
|
||||
_ = huma.WriteErr(api, ctx, http.StatusInternalServerError, "Internal Server Error")
|
||||
return
|
||||
}
|
||||
ctx.SetHeader(QueueHeader, id.String())
|
||||
next(huma.WithValue(ctx, queueKey{}, id))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user