From: Diogo Franco (Kovensky) Date: Fri, 26 Jul 2013 02:48:43 +0000 (-0300) Subject: anidb: Update the MyListAnime when running a mylist file query X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=1de6288998b3fdf9efd8e6d879108c4401f20e49;p=go-anidb.git anidb: Update the MyListAnime when running a mylist file query Keeps the MyListAnime's cached timestamp as it was before the update, since this is updating a non-up-to-date view of MyListAnime. --- diff --git a/intent.go b/intent.go index 88b5a3f..1ba0811 100644 --- a/intent.go +++ b/intent.go @@ -94,7 +94,9 @@ func (m *intentMapStruct) _free(is *intentStruct, keys ...fscache.CacheKey) { // deletes the key before unlocking, Intent needs to recheck key status delete(m.m, intentKey(keys...)) // better than unlocking then deleting -- could delete a "brand new" entry - is.Unlock() + if is != nil { + is.Unlock() + } } // Notifies and closes all channels that are listening for the specified keys; @@ -108,7 +110,9 @@ func (m *intentMapStruct) NotifyClose(v notification, keys ...fscache.CacheKey) is := m._lockIntent(keys...) defer m._free(is, keys...) - is.NotifyClose(v) + if is != nil { + is.NotifyClose(v) + } } // Closes all channels that are listening for the specified keys @@ -120,7 +124,9 @@ func (m *intentMapStruct) Close(keys ...fscache.CacheKey) { is := m._lockIntent(keys...) defer m._free(is, keys...) - is.Close() + if is != nil { + is.Close() + } } // Notifies all channels that are listening for the specified keys, @@ -130,22 +136,28 @@ func (m *intentMapStruct) Notify(v notification, keys ...fscache.CacheKey) { defer m.Unlock() is := m._lockIntent(keys...) - defer is.Unlock() + if is != nil { + defer is.Unlock() - is.Notify(v) + is.Notify(v) + } } // NOTE: does not lock the stuct func (s *intentStruct) Notify(v notification) { for _, ch := range s.chs { - ch <- v + if ch != nil { + ch <- v + } } } // NOTE: does not lock the struct func (s *intentStruct) Close() { for _, ch := range s.chs { - close(ch) + if ch != nil { + close(ch) + } } s.chs = nil } @@ -153,8 +165,10 @@ func (s *intentStruct) Close() { // NOTE: does not lock the struct func (s *intentStruct) NotifyClose(v notification) { for _, ch := range s.chs { - ch <- v - close(ch) + if ch != nil { + ch <- v + close(ch) + } } s.chs = nil } diff --git a/mylistanimecache.go b/mylistanimecache.go index 2ea8325..3fa165b 100644 --- a/mylistanimecache.go +++ b/mylistanimecache.go @@ -48,7 +48,7 @@ func (adb *AniDB) MyListAnime(aid AID) <-chan *MyListAnime { } key := []fscache.CacheKey{"mylist-anime", user.UID, aid} - ic := make(chan notification, 1) + ic := make(chan notification, 2) go func() { ch <- (<-ic).(*MyListAnime); close(ch) }() if intentMap.Intent(ic, key...) { return diff --git a/mylistcache.go b/mylistcache.go index d7ad4eb..08e94b3 100644 --- a/mylistcache.go +++ b/mylistcache.go @@ -205,12 +205,51 @@ func (adb *AniDB) parseMylistReply(reply udpapi.APIReply) *MyListEntry { if f := e.FID.File(); f != nil { f.LID[user.UID] = e.LID cacheFile(f) + + now := time.Now() + mla := <-adb.MyListAnime(f.AID) + + key := []fscache.CacheKey{"mylist-anime", user.UID, f.AID} + + intentMap.Intent(nil, key...) + + if mla == nil { + mla = &MyListAnime{} + } + + if mla.Cached.Before(now) { + el := mla.EpisodesWithState[e.MyListState] + el.Add(f.EpisodeNumber) + mla.EpisodesWithState[e.MyListState] = el + + if e.DateWatched.IsZero() { + mla.WatchedEpisodes.Sub(f.EpisodeNumber) + } else { + mla.WatchedEpisodes.Add(f.EpisodeNumber) + } + + eg := mla.EpisodesPerGroup[f.GID] + eg.Add(f.EpisodeNumber) + mla.EpisodesPerGroup[f.GID] = eg + + if mla.Cached.IsZero() { + // as attractive as such an ancient mtime would be, + // few filesystems can represent it; just make it old enough + mla.Cached = now.Add(-2 * MyListCacheDuration) + } + + Cache.Set(mla, key...) + Cache.Chtime(mla.Cached, key...) + } + + // this unfortunately races if Intent returns true: + // only the first NotifyClose call actually notifies + go intentMap.NotifyClose(mla, key...) } CacheSet(e, "mylist", "by-fid", e.FID, user.UID) } - // TODO: Add mylist info to Anime, also update there CacheSet(e, "mylist", e.LID) return e