1package task
2
3import (
4	"context"
5	"encoding/json"
6	"github.com/automuteus/utils/pkg/rediskey"
7	"github.com/go-redis/redis/v8"
8	"time"
9)
10
11type JobType int
12
13const (
14	ConnectionJob JobType = iota
15	LobbyJob
16	StateJob
17	PlayerJob
18	GameOverJob
19)
20
21type Job struct {
22	JobType JobType     `json:"type"`
23	Payload interface{} `json:"payload"`
24}
25
26const JobTTLSeconds = 3600
27
28func PushJob(ctx context.Context, redis *redis.Client, connCode string, jobType JobType, payload string) error {
29	job := Job{
30		JobType: jobType,
31		Payload: payload,
32	}
33	jBytes, err := json.Marshal(job)
34	if err != nil {
35		return err
36	}
37
38	count, err := redis.RPush(ctx, rediskey.JobNamespace+connCode, string(jBytes)).Result()
39	if err == nil {
40		notify(ctx, redis, connCode)
41	}
42
43	// new list
44	if count < 2 {
45		// log.Printf("Set TTL for List")
46		redis.Expire(ctx, rediskey.JobNamespace+connCode, JobTTLSeconds*time.Second)
47	}
48
49	return err
50}
51
52func notify(ctx context.Context, redis *redis.Client, connCode string) {
53	redis.Publish(ctx, rediskey.JobNamespace+connCode+":notify", true)
54}
55
56func Subscribe(ctx context.Context, redis *redis.Client, connCode string) *redis.PubSub {
57	return redis.Subscribe(ctx, rediskey.JobNamespace+connCode+":notify")
58}
59
60func PopJob(ctx context.Context, redis *redis.Client, connCode string) (Job, error) {
61	str, err := redis.LPop(ctx, rediskey.JobNamespace+connCode).Result()
62
63	j := Job{}
64	if err != nil {
65		return j, err
66	}
67	err = json.Unmarshal([]byte(str), &j)
68	return j, err
69}
70
71func Ack(ctx context.Context, redis *redis.Client, connCode string) {
72	redis.Publish(ctx, rediskey.JobNamespace+connCode+":ack", true)
73}
74
75func AckSubscribe(ctx context.Context, redis *redis.Client, connCode string) *redis.PubSub {
76	return redis.Subscribe(ctx, rediskey.JobNamespace+connCode+":ack")
77}
78