67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
|
package joke
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"strconv"
|
||
|
"time"
|
||
|
|
||
|
"github.com/allegro/bigcache/v3"
|
||
|
"github.com/go-redis/redis/v8"
|
||
|
"github.com/minio/minio-go/v7"
|
||
|
)
|
||
|
|
||
|
func GetTotalJoke(ctx context.Context, bucket *minio.Client, cache *redis.Client, memory *bigcache.BigCache) (int, error) {
|
||
|
totalJokesFromMemory, err := memory.Get("total")
|
||
|
if err != nil && !errors.Is(err, bigcache.ErrEntryNotFound) {
|
||
|
return 0, fmt.Errorf("acquiring total joke from memory: %w", err)
|
||
|
}
|
||
|
|
||
|
if err == nil {
|
||
|
total, err := strconv.Atoi(string(totalJokesFromMemory))
|
||
|
if err != nil {
|
||
|
return 0, fmt.Errorf("parsing string to int: %w", err)
|
||
|
}
|
||
|
|
||
|
return total, nil
|
||
|
}
|
||
|
|
||
|
totalJokesFromCache, err := cache.Get(ctx, "jokes:total").Result()
|
||
|
if err != nil && !errors.Is(err, redis.Nil) {
|
||
|
return 0, fmt.Errorf("acquiring total joke from redis: %w", err)
|
||
|
}
|
||
|
|
||
|
if err == nil {
|
||
|
total, err := strconv.Atoi(string(totalJokesFromCache))
|
||
|
if err != nil {
|
||
|
return 0, fmt.Errorf("parsing string to int: %w", err)
|
||
|
}
|
||
|
|
||
|
return total, nil
|
||
|
}
|
||
|
|
||
|
jokes, err := ListJokesFromBucket(ctx, bucket, cache)
|
||
|
if err != nil {
|
||
|
return 0, fmt.Errorf("listing jokes: %w", err)
|
||
|
}
|
||
|
|
||
|
defer func(total int) {
|
||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||
|
defer cancel()
|
||
|
|
||
|
err := cache.Set(ctx, "jokes:total", strconv.Itoa(total), time.Hour*3).Err()
|
||
|
if err != nil {
|
||
|
log.Printf("setting total jokes to redis: %s", err.Error())
|
||
|
}
|
||
|
|
||
|
err = memory.Set("total", []byte(strconv.Itoa(total)))
|
||
|
if err != nil {
|
||
|
log.Printf("setting total jokes to memory: %s", err.Error())
|
||
|
}
|
||
|
}(len(jokes))
|
||
|
|
||
|
return len(jokes), nil
|
||
|
}
|