topfreegames/khan

View on GitHub
caches/clan.go

Summary

Maintainability
A
0 mins
Test Coverage
package caches

import (
    "fmt"

    gocache "github.com/patrickmn/go-cache"
    "github.com/topfreegames/khan/models"
)

// ClansSummaries represents a cache for the RetrieveClansSummaries operation.
type ClansSummaries struct {
    // Cache points to an instance of gocache.Cache used as the backend cache object.
    Cache *gocache.Cache
}

// GetClansSummaries is a cache in front of models.GetClansSummaries() with the exact same interface.
// Like models.GetClansSummaries(), this function may return partial results + CouldNotFindAllClansError.
// The map[string]interface{} return type represents a summary of one clan with the following keys/values:
// "membershipCount":  int
// "publicID":         string
// "metadata":         map[string]interface{} (user-defined arbitrary JSON object with clan metadata)
// "name":             string
// "allowApplication": bool
// "autoJoin":         bool
// TODO(matheuscscp): replace this map with a richer type
func (c *ClansSummaries) GetClansSummaries(db models.DB, gameID string, publicIDs []string) ([]map[string]interface{}, error) {
    // first, assemble a result map with cached payloads. also assemble a missingPublicIDs string slice
    idToPayload := make(map[string]map[string]interface{})
    var missingPublicIDs []string
    for _, publicID := range publicIDs {
        if clanPayload, present := c.Cache.Get(c.getClanSummaryCacheKey(gameID, publicID)); present {
            idToPayload[publicID] = clanPayload.(map[string]interface{})
        } else {
            missingPublicIDs = append(missingPublicIDs, publicID)
        }
    }

    // fetch and cache missing clans
    var err error
    if len(missingPublicIDs) > 0 {
        // fetch
        var clans []map[string]interface{}
        clans, err = models.GetClansSummaries(db, gameID, missingPublicIDs)
        if err != nil {
            if _, ok := err.(*models.CouldNotFindAllClansError); !ok {
                return nil, err
            }
        }

        // cache
        for _, clanPayload := range clans {
            publicID := clanPayload["publicID"].(string)
            idToPayload[publicID] = clanPayload
            c.Cache.Set(c.getClanSummaryCacheKey(gameID, publicID), clanPayload, gocache.DefaultExpiration)
        }
    }

    // assemble final result with input order
    var result []map[string]interface{}
    for _, publicID := range publicIDs {
        if summary, ok := idToPayload[publicID]; ok {
            result = append(result, summary)
        }
    }
    return result, err
}

func (c *ClansSummaries) getClanSummaryCacheKey(gameID, publicID string) string {
    return fmt.Sprintf("%s/%s", gameID, publicID)
}