package host
import (
"encoding/json"
"errors"
"github.com/navidrome/navidrome/plugins/pdk/go/pdk"
)
type QueueConfig struct {
Concurrency int32 `json:"concurrency"`
MaxRetries int32 `json:"maxRetries"`
BackoffMs int64 `json:"backoffMs"`
DelayMs int64 `json:"delayMs"`
RetentionMs int64 `json:"retentionMs"`
}
type TaskInfo struct {
Status string `json:"status"`
Message string `json:"message"`
Attempt int32 `json:"attempt"`
}
func task_createqueue(uint64) uint64
func task_enqueue(uint64) uint64
func task_get(uint64) uint64
func task_cancel(uint64) uint64
func task_clearqueue(uint64) uint64
type taskCreateQueueRequest struct {
Name string `json:"name"`
Config QueueConfig `json:"config"`
}
type taskEnqueueRequest struct {
QueueName string `json:"queueName"`
Payload []byte `json:"payload"`
}
type taskEnqueueResponse struct {
Result string `json:"result,omitempty"`
Error string `json:"error,omitempty"`
}
type taskGetRequest struct {
TaskID string `json:"taskId"`
}
type taskGetResponse struct {
Result *TaskInfo `json:"result,omitempty"`
Error string `json:"error,omitempty"`
}
type taskCancelRequest struct {
TaskID string `json:"taskId"`
}
type taskClearQueueRequest struct {
QueueName string `json:"queueName"`
}
type taskClearQueueResponse struct {
Result int64 `json:"result,omitempty"`
Error string `json:"error,omitempty"`
}
func TaskCreateQueue(name string, config QueueConfig) error {
req := taskCreateQueueRequest{
Name: name,
Config: config,
}
reqBytes, err := json.Marshal(req)
if err != nil {
return err
}
reqMem := pdk.AllocateBytes(reqBytes)
defer reqMem.Free()
responsePtr := task_createqueue(reqMem.Offset())
responseMem := pdk.FindMemory(responsePtr)
responseBytes := responseMem.ReadBytes()
var response struct {
Error string `json:"error,omitempty"`
}
if err := json.Unmarshal(responseBytes, &response); err != nil {
return err
}
if response.Error != "" {
return errors.New(response.Error)
}
return nil
}
func TaskEnqueue(queueName string, payload []byte) (string, error) {
req := taskEnqueueRequest{
QueueName: queueName,
Payload: payload,
}
reqBytes, err := json.Marshal(req)
if err != nil {
return "", err
}
reqMem := pdk.AllocateBytes(reqBytes)
defer reqMem.Free()
responsePtr := task_enqueue(reqMem.Offset())
responseMem := pdk.FindMemory(responsePtr)
responseBytes := responseMem.ReadBytes()
var response taskEnqueueResponse
if err := json.Unmarshal(responseBytes, &response); err != nil {
return "", err
}
if response.Error != "" {
return "", errors.New(response.Error)
}
return response.Result, nil
}
func TaskGet(taskID string) (*TaskInfo, error) {
req := taskGetRequest{
TaskID: taskID,
}
reqBytes, err := json.Marshal(req)
if err != nil {
return nil, err
}
reqMem := pdk.AllocateBytes(reqBytes)
defer reqMem.Free()
responsePtr := task_get(reqMem.Offset())
responseMem := pdk.FindMemory(responsePtr)
responseBytes := responseMem.ReadBytes()
var response taskGetResponse
if err := json.Unmarshal(responseBytes, &response); err != nil {
return nil, err
}
if response.Error != "" {
return nil, errors.New(response.Error)
}
return response.Result, nil
}
func TaskCancel(taskID string) error {
req := taskCancelRequest{
TaskID: taskID,
}
reqBytes, err := json.Marshal(req)
if err != nil {
return err
}
reqMem := pdk.AllocateBytes(reqBytes)
defer reqMem.Free()
responsePtr := task_cancel(reqMem.Offset())
responseMem := pdk.FindMemory(responsePtr)
responseBytes := responseMem.ReadBytes()
var response struct {
Error string `json:"error,omitempty"`
}
if err := json.Unmarshal(responseBytes, &response); err != nil {
return err
}
if response.Error != "" {
return errors.New(response.Error)
}
return nil
}
func TaskClearQueue(queueName string) (int64, error) {
req := taskClearQueueRequest{
QueueName: queueName,
}
reqBytes, err := json.Marshal(req)
if err != nil {
return 0, err
}
reqMem := pdk.AllocateBytes(reqBytes)
defer reqMem.Free()
responsePtr := task_clearqueue(reqMem.Offset())
responseMem := pdk.FindMemory(responsePtr)
responseBytes := responseMem.ReadBytes()
var response taskClearQueueResponse
if err := json.Unmarshal(responseBytes, &response); err != nil {
return 0, err
}
if response.Error != "" {
return 0, errors.New(response.Error)
}
return response.Result, nil
}