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/EliasFleckenstein03/go-anidb/http"
+ "github.com/EliasFleckenstein03/go-anidb/misc"
+ "github.com/EliasFleckenstein03/go-anidb/udp"
+ "github.com/EliasFleckenstein03/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
// 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 {
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}
}()
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...)
}
switch resp.anime.Error {
case "Anime not found", "aid Missing or Invalid":
// deleted AID?
- cache.Delete(keys...)
+ Cache.Delete(key...)
}
ok = false
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
}
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