X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=animecache.go;h=eff4df677e73928339bfee4caccd81bdafda0bcb;hb=d5fc5a1b93c9361c08d181a1cb4dca447e9edf84;hp=64581a0cdbe486f4f9f4515d4f9407ae0eefadd0;hpb=db0386bd127a34c60e7d51853c179a3a3521529c;p=go-anidb.git diff --git a/animecache.go b/animecache.go index 64581a0..eff4df6 100644 --- a/animecache.go +++ b/animecache.go @@ -1,49 +1,47 @@ package anidb import ( - "encoding/gob" "fmt" "github.com/Kovensky/go-anidb/http" "github.com/Kovensky/go-anidb/misc" "github.com/Kovensky/go-anidb/udp" - "log" + "github.com/Kovensky/go-fscache" "sort" "strconv" "strings" "time" ) -func init() { - gob.RegisterName("*github.com/Kovensky/go-anidb.Anime", &Anime{}) - gob.RegisterName("github.com/Kovensky/go-anidb.AID", AID(0)) -} +var _ cacheable = &Anime{} -func (a *Anime) Touch() { - a.Cached = time.Now() +func (a *Anime) setCachedTS(ts time.Time) { + a.Cached = ts } func (a *Anime) IsStale() bool { if a == nil { return true } + now := time.Now() + diff := now.Sub(a.Cached) if a.Incomplete { - return time.Now().Sub(a.Cached) > AnimeIncompleteCacheDuration + return diff > AnimeIncompleteCacheDuration + } + + // If the anime ended, and more than AnimeCacheDuration time ago at that + if !a.EndDate.IsZero() && now.After(a.EndDate.Add(AnimeCacheDuration)) { + return diff > FinishedAnimeCacheDuration } - return time.Now().Sub(a.Cached) > AnimeCacheDuration + return diff > AnimeCacheDuration } // Unique Anime IDentifier. type AID int -// make AID Cacheable - -func (e AID) Touch() {} -func (e AID) IsStale() bool { return false } - // Returns a cached Anime. Returns nil if there is no cached Anime with this AID. func (aid AID) Anime() *Anime { var a Anime - if cache.Get(&a, "aid", aid) == nil { + if CacheGet(&a, "aid", aid) == nil { return &a } return nil @@ -57,7 +55,7 @@ type httpAnimeResponse struct { // Retrieves an Anime by its AID. Uses both the HTTP and UDP APIs, // but can work without the UDP API. func (adb *AniDB) AnimeByID(aid AID) <-chan *Anime { - keys := []cacheKey{"aid", aid} + key := []fscache.CacheKey{"aid", aid} ch := make(chan *Anime, 1) if aid < 1 { @@ -65,27 +63,27 @@ func (adb *AniDB) AnimeByID(aid AID) <-chan *Anime { close(ch) } - ic := make(chan Cacheable, 1) + ic := make(chan notification, 1) go func() { ch <- (<-ic).(*Anime); close(ch) }() - if intentMap.Intent(ic, keys...) { + if intentMap.Intent(ic, key...) { return ch } - if !cache.CheckValid(keys...) { - intentMap.NotifyClose((*Anime)(nil), keys...) + if !Cache.IsValid(InvalidKeyCacheDuration, key...) { + intentMap.NotifyClose((*Anime)(nil), key...) return ch } anime := aid.Anime() if !anime.IsStale() { - intentMap.NotifyClose(anime, keys...) + intentMap.NotifyClose(anime, key...) return ch } go func() { httpChan := make(chan httpAnimeResponse, 1) go func() { - log.Printf("HTTP>>> Anime %d", aid) + adb.Logger.Printf("HTTP>>> Anime %d", aid) a, err := httpapi.GetAnime(int(aid)) httpChan <- httpAnimeResponse{anime: a, err: err} }() @@ -110,31 +108,32 @@ func (adb *AniDB) AnimeByID(aid AID) <-chan *Anime { case <-timeout: // HTTP API timeout if httpChan != nil { - log.Printf("HTTP<<< Timeout") + adb.Logger.Printf("HTTP<<< Timeout") close(httpChan) } case resp := <-httpChan: if resp.err != nil { - log.Printf("HTTP<<< %v", resp.err) + adb.Logger.Printf("HTTP<<< %v", resp.err) ok = false break Loop } if resp.anime.Error != "" { - log.Printf("HTTP<<< Error %q", resp.anime.Error) + adb.Logger.Printf("HTTP<<< Error %q", resp.anime.Error) } if anime.populateFromHTTP(resp.anime) { - log.Printf("HTTP<<< Anime %q", anime.PrimaryTitle) + adb.Logger.Printf("HTTP<<< Anime %q", anime.PrimaryTitle) } else { // HTTP ok but parsing not ok if anime.PrimaryTitle == "" { - cache.MarkInvalid(keys...) + Cache.SetInvalid(key...) } - if resp.anime.Error == "Anime not found" { + switch resp.anime.Error { + case "Anime not found", "aid Missing or Invalid": // deleted AID? - cache.Delete(keys...) + Cache.Delete(key...) } ok = false @@ -144,9 +143,9 @@ func (adb *AniDB) AnimeByID(aid AID) <-chan *Anime { httpChan = nil case reply := <-udpChan: if reply.Code() == 330 { - cache.MarkInvalid(keys...) + Cache.SetInvalid(key...) // deleted AID? - cache.Delete(keys...) + Cache.Delete(key...) ok = false break Loop @@ -158,11 +157,11 @@ func (adb *AniDB) AnimeByID(aid AID) <-chan *Anime { } if anime.PrimaryTitle != "" { if ok { - cache.Set(anime, keys...) + CacheSet(anime, key...) } - intentMap.NotifyClose(anime, keys...) + intentMap.NotifyClose(anime, key...) } else { - intentMap.NotifyClose((*Anime)(nil), keys...) + intentMap.NotifyClose((*Anime)(nil), key...) } }() return ch