jokes-bapak2/api/core/joke/getter.go

98 lines
2.6 KiB
Go
Raw Normal View History

package joke
import (
"context"
2022-09-03 10:53:46 +00:00
"encoding/hex"
"errors"
2022-09-03 10:53:46 +00:00
"fmt"
"io"
"log"
"math/rand"
"strconv"
2022-09-03 10:53:46 +00:00
"time"
"github.com/allegro/bigcache/v3"
2022-09-03 10:53:46 +00:00
"github.com/go-redis/redis/v8"
"github.com/minio/minio-go/v7"
)
2022-09-03 10:53:46 +00:00
func GetRandomJoke(ctx context.Context, bucket *minio.Client, cache *redis.Client, memory *bigcache.BigCache) (image []byte, contentType string, err error) {
totalJokes, err := GetTotalJoke(ctx, bucket, cache, memory)
if err != nil {
2022-09-03 10:53:46 +00:00
return []byte{}, "", fmt.Errorf("getting total joke: %w", err)
}
2022-09-03 10:53:46 +00:00
randomIndex := rand.Intn(totalJokes - 1)
2022-09-03 10:53:46 +00:00
joke, contentType, err := GetJokeById(ctx, bucket, cache, memory, randomIndex)
if err != nil {
2022-09-03 10:53:46 +00:00
return []byte{}, "", fmt.Errorf("getting joke by id: %w", err)
}
2022-09-03 10:53:46 +00:00
return joke, contentType, nil
}
2022-09-03 10:53:46 +00:00
func GetJokeById(ctx context.Context, bucket *minio.Client, cache *redis.Client, memory *bigcache.BigCache, id int) (image []byte, contentType string, err error) {
jokeFromMemory, err := memory.Get("id:" + strconv.Itoa(id))
if err != nil && !errors.Is(err, bigcache.ErrEntryNotFound) {
return []byte{}, "", fmt.Errorf("acquiring joke from memory: %w", err)
}
2022-09-03 10:53:46 +00:00
if err == nil {
return jokeFromMemory, "", nil
}
2022-09-03 10:53:46 +00:00
jokeFromCache, err := cache.Get(ctx, "jokes:id:"+strconv.Itoa(id)).Result()
if err != nil {
2022-09-03 10:53:46 +00:00
// Decode hex string to bytes
imageBytes, err := hex.DecodeString(jokeFromCache)
if err != nil {
return []byte{}, "", fmt.Errorf("decoding hex string: %w", err)
}
2022-09-03 10:53:46 +00:00
defer func(id int, imageBytes []byte) {
err := memory.Set("id:"+strconv.Itoa(id), imageBytes)
if err != nil {
log.Printf("setting memory cache: %s", err.Error())
}
}(id, imageBytes)
2022-09-03 10:53:46 +00:00
return imageBytes, "", nil
2021-07-17 10:34:02 +00:00
}
2022-09-03 10:53:46 +00:00
jokes, err := ListJokesFromBucket(ctx, bucket, cache)
if err != nil {
2022-09-03 10:53:46 +00:00
return []byte{}, "", fmt.Errorf("listing jokes: %w", err)
}
2022-09-03 10:53:46 +00:00
object, err := bucket.GetObject(ctx, JokesBapak2Bucket, jokes[id].FileName, minio.GetObjectOptions{})
2021-07-19 10:21:08 +00:00
if err != nil {
2022-09-03 10:53:46 +00:00
return []byte{}, "", fmt.Errorf("getting object: %w", err)
2021-07-19 10:21:08 +00:00
}
2022-09-03 10:53:46 +00:00
defer func() {
err := object.Close()
if err != nil {
log.Printf("closing image reader: %s", err.Error())
}
2022-09-03 10:53:46 +00:00
}()
2022-09-03 10:53:46 +00:00
image, err = io.ReadAll(object)
if err != nil {
2022-09-03 10:53:46 +00:00
return []byte{}, "", fmt.Errorf("reading object: %w", err)
}
2022-09-03 10:53:46 +00:00
defer func(id int, image []byte) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
2022-09-03 10:53:46 +00:00
imageString := hex.EncodeToString(image)
2021-07-19 10:21:08 +00:00
2022-09-03 10:53:46 +00:00
err := cache.Set(ctx, "jokes:id:"+strconv.Itoa(id), imageString, time.Hour*1).Err()
if err != nil {
log.Printf("setting cache: %s", err.Error())
2021-07-19 10:21:08 +00:00
}
2022-09-03 10:53:46 +00:00
}(id, image)
2022-09-03 10:53:46 +00:00
return image, jokes[id].ContentType, nil
}