X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=animecache.go;h=99b89015081833512858db5923f88c6d9bc93429;hb=d32928667949b2815adea455690fd71fb747400f;hp=948d257906c0c016dac550834a5b0a37f6f02638;hpb=e54415863fb1aaa9a12d4a351557667f2d668c30;p=go-anidb.git diff --git a/animecache.go b/animecache.go index 948d257..99b8901 100644 --- a/animecache.go +++ b/animecache.go @@ -35,6 +35,7 @@ func (a *Anime) IsStale() bool { type AID int // make AID Cacheable + func (e AID) Touch() {} func (e AID) IsStale() bool { return false } @@ -52,15 +53,17 @@ type httpAnimeResponse struct { err error } -// Retrieves an Anime from the cache if possible. If it isn't cached, -// or if the cache is stale, queries both the UDP and HTTP APIs -// for data. -// -// Note: This can take at least 4 seconds during heavy traffic. +// 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} ch := make(chan *Anime, 1) + if aid < 1 { + ch <- nil + close(ch) + } + ic := make(chan Cacheable, 1) go func() { ch <- (<-ic).(*Anime); close(ch) }() if intentMap.Intent(ic, keys...) { @@ -68,13 +71,13 @@ func (adb *AniDB) AnimeByID(aid AID) <-chan *Anime { } if !cache.CheckValid(keys...) { - intentMap.Notify((*Anime)(nil), keys...) + intentMap.NotifyClose((*Anime)(nil), keys...) return ch } anime := aid.Anime() if !anime.IsStale() { - intentMap.Notify(anime, keys...) + intentMap.NotifyClose(anime, keys...) return ch } @@ -109,21 +112,30 @@ func (adb *AniDB) AnimeByID(aid AID) <-chan *Anime { ok = false break Loop } - if a := anime.populateFromHTTP(resp.anime); a == nil { + if !anime.populateFromHTTP(resp.anime) { // HTTP ok but parsing not ok if anime.PrimaryTitle == "" { cache.MarkInvalid(keys...) } + if resp.anime.Error == "Anime not found" { + // deleted AID? + cache.Delete(keys...) + } + ok = false break Loop - } else { - anime = a } + httpChan = nil case reply := <-udpChan: if reply.Code() == 330 { cache.MarkInvalid(keys...) + // deleted AID? + cache.Delete(keys...) + + ok = false + break Loop } else { anime.Incomplete = !anime.populateFromUDP(reply) } @@ -134,17 +146,17 @@ func (adb *AniDB) AnimeByID(aid AID) <-chan *Anime { if ok { cache.Set(anime, keys...) } - intentMap.Notify(anime, keys...) + intentMap.NotifyClose(anime, keys...) } else { - intentMap.Notify((*Anime)(nil), keys...) + intentMap.NotifyClose((*Anime)(nil), keys...) } }() return ch } -func (a *Anime) populateFromHTTP(reply httpapi.Anime) *Anime { +func (a *Anime) populateFromHTTP(reply httpapi.Anime) bool { if reply.Error != "" { - return (*Anime)(nil) + return false } if a.AID != AID(reply.ID) { @@ -220,7 +232,7 @@ func (a *Anime) populateFromHTTP(reply httpapi.Anime) *Anime { titles[Language(title.Lang)] = title.Title } - e := Episode{ + e := &Episode{ EID: EID(ep.ID), AID: a.AID, @@ -236,12 +248,12 @@ func (a *Anime) populateFromHTTP(reply httpapi.Anime) *Anime { Titles: titles, } counts[e.Type]++ - cacheEpisode(&e) + cacheEpisode(e) a.Episodes = append(a.Episodes, e) } - a.EpisodeCount = EpisodeCount{ + a.EpisodeCount = misc.EpisodeCount{ RegularCount: counts[misc.EpisodeTypeRegular], SpecialCount: counts[misc.EpisodeTypeSpecial], CreditsCount: counts[misc.EpisodeTypeCredits], @@ -256,7 +268,7 @@ func (a *Anime) populateFromHTTP(reply httpapi.Anime) *Anime { } } - return a + return true } func (a *Anime) populateResources(list []httpapi.Resource) {