package data import ( "context" "errors" "emtlabs.com/spotify-sync/api" log "github.com/sirupsen/logrus" clientv3 "go.etcd.io/etcd/client/v3" "gopkg.in/yaml.v3" ) const speaker_base_key string = "/v1/speaker" const default_speaker_lease_time int64 = 10 var slog *log.Entry func initSpeaker() error { slog = dlog.WithField("data", "speaker") return nil } // buildSpeakerKey returns the key for a given speaker by id func buildSpeakerKey(id string) string { return speaker_base_key + "/" + id } // GetSpeaker returns a speaker by id func GetSpeaker(id string) (*api.Speaker, error) { //set log l := slog.WithField("method", "get") l.Debugln("getting current speaker state from db") ctx := context.Background() sk := buildSpeakerKey(id) resp, err := Client.Get(ctx, sk) if err != nil { l.Errorln(err) return nil, err } if resp.Count == 0 { l.Warningln("speaker not available") return nil, err } else if resp.Count > 1 { err = errors.New("multiple speaker available on same path") l.Errorln(err) return nil, err } //decode playout speaker := api.Speaker{} resp_raw := resp.Kvs[0].Value err = yaml.Unmarshal(resp_raw, &speaker) if err != nil { l.Errorln(err) return nil, err } l.Debugln("speaker state in db (", speaker, ")") return &speaker, nil } // SendHeartbeat sends a speaker state to the db func SendHeartbeat(speaker *api.Speaker) error { l := plog.WithField("method", "put") data, err := yaml.Marshal(speaker) if err != nil { l.Errorln(err) return err } l.Debugln("sending speaker to db", string(data)) sk := buildSpeakerKey(speaker.Id) ctx := context.Background() lease, err := Client.Grant(ctx, default_speaker_lease_time) if err != nil { l.Errorln(err) return err } ctx = context.Background() _, err = Client.KV.Put(ctx, sk, string(data), clientv3.WithLease(lease.ID)) if err != nil { l.Errorln(err) return err } return nil } // GetSpeakers returns a list of all speakers func GetSpeakers() ([]api.Speaker, error) { //set log l := slog.WithField("method", "list") l.Debugln("list speaker states from db") ctx := context.Background() resp, err := Client.Get(ctx, speaker_base_key, clientv3.WithPrefix()) if err != nil { l.Errorln(err) return nil, err } resp_list := make([]api.Speaker, 0) //decode speaker for _, v := range resp.Kvs { speaker := api.Speaker{} err = yaml.Unmarshal(v.Value, &speaker) if err != nil { l.Warnln(err) continue } resp_list = append(resp_list, speaker) } l.Debugln(len(resp_list), " speaker states read from db") return resp_list, nil }