type AID int
// make AID Cacheable
+
func (e AID) Touch() {}
func (e AID) IsStale() bool { return false }
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...) {
}
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
}
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)
}
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) {
titles[Language(title.Lang)] = title.Title
}
- e := Episode{
+ e := &Episode{
EID: EID(ep.ID),
AID: a.AID,
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],
}
}
- return a
+ return true
}
func (a *Anime) populateResources(list []httpapi.Resource) {