package anidb
import (
- "encoding/gob"
+ "github.com/EliasFleckenstein03/go-fscache"
"strconv"
"strings"
"time"
)
-func init() {
- gob.RegisterName("*github.com/Kovensky/go-anidb.Episode", &Episode{})
-}
+var _ cacheable = &Episode{}
-func (e *Episode) Touch() {
- e.Cached = time.Now()
+func (e *Episode) setCachedTS(ts time.Time) {
+ e.Cached = ts
}
func (e *Episode) IsStale() bool {
// Retrieves the Episode corresponding to this EID from the cache.
func (eid EID) Episode() *Episode {
var e Episode
- if cache.Get(&e, "eid", eid) == nil {
+ if CacheGet(&e, "eid", eid) == nil {
return &e
}
return nil
}
func cacheEpisode(ep *Episode) {
- cache.Set(ep.AID, "aid", "by-eid", ep.EID)
- cache.Set(ep, "eid", ep.EID)
+ CacheSet(ep.AID, "aid", "by-eid", ep.EID)
+ CacheSet(ep, "eid", ep.EID)
}
// Retrieves an Episode by its EID.
// to an Anime query. Otherwise, uses both the HTTP and UDP
// APIs to retrieve it.
func (adb *AniDB) EpisodeByID(eid EID) <-chan *Episode {
- keys := []cacheKey{"eid", eid}
+ key := []fscache.CacheKey{"eid", eid}
ch := make(chan *Episode, 1)
if eid < 1 {
return ch
}
- ic := make(chan Cacheable, 1)
+ ic := make(chan notification, 1)
go func() { ch <- (<-ic).(*Episode); close(ch) }()
- if intentMap.Intent(ic, keys...) {
+ if intentMap.Intent(ic, key...) {
return ch
}
- if !cache.CheckValid(keys...) {
- intentMap.Notify((*Episode)(nil), keys...)
+ if !Cache.IsValid(InvalidKeyCacheDuration, key...) {
+ intentMap.NotifyClose((*Episode)(nil), key...)
return ch
}
e := eid.Episode()
if !e.IsStale() {
- intentMap.Notify(e, keys...)
+ intentMap.NotifyClose(e, key...)
return ch
}
go func() {
- // The UDP API data is worse than the HTTP API anime data,
- // try and get from the corresponding Anime
+ // The UDP API data is worse than the HTTP API anime data and
+ // might even get truncated on some pathological cases;
+ // try and get from the corresponding Anime, which uses the HTTP
+ // API episode list.
aid := AID(0)
- ok := cache.Get(&aid, "aid", "by-eid", eid) == nil
+ _, err := Cache.Get(&aid, "aid", "by-eid", eid)
+ ok := err == nil
udpDone := false
break
}
} else if reply.Code() == 340 {
- cache.MarkInvalid(keys...)
- cache.Delete(keys...) // deleted EID?
+ Cache.SetInvalid(key...)
break
} else {
break
}
udpDone = true
}
- a := <-adb.AnimeByID(AID(aid)) // this caches episodes...
- ep := eid.Episode() // ...so this is now a cache hit
+ a := <-adb.AnimeByID(AID(aid)) // updates the episode cache as well
+ ep := a.EpisodeByEID(eid)
- if !ep.IsStale() {
+ if ep != nil {
e = ep
break
} else {
- // check to see if we looked in the right AID
- found := false
- if a != nil {
- for _, ep := range a.Episodes {
- if eid == ep.EID {
- found = true
- break
- }
- }
- }
-
- // if found, then it's just that the anime is also stale (offline?)
- if found {
- break
- } else {
- // otherwise, the EID<->AID map broke
- ok = false
- cache.Delete("aid", "by-eid", eid)
- }
+ // the EID<->AID map broke
+ ok = false
+ Cache.Delete("aid", "by-eid", eid)
}
}
- intentMap.Notify(e, keys...)
+ intentMap.NotifyClose(e, key...)
}()
return ch
}