]> git.lizzy.rs Git - go-anidb.git/commitdiff
anidb: Update the MyListAnime when running a mylist file query
authorDiogo Franco (Kovensky) <diogomfranco@gmail.com>
Fri, 26 Jul 2013 02:48:43 +0000 (23:48 -0300)
committerDiogo Franco (Kovensky) <diogomfranco@gmail.com>
Fri, 26 Jul 2013 02:48:43 +0000 (23:48 -0300)
Keeps the MyListAnime's cached timestamp as it was before the update, since
this is updating a non-up-to-date view of MyListAnime.

intent.go
mylistanimecache.go
mylistcache.go

index 88b5a3f3d3a668d6e7b2367c68662a5150d5ef01..1ba0811853927201a3d934ad9ef0ae64262553d8 100644 (file)
--- 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
 }
index 2ea83254ae0e07a2d2e351e19dd340a2c3f446a0..3fa165b87bd491bcfef70a387ad5faf44c32048d 100644 (file)
@@ -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
index d7ad4ebe9591e7f18f7bdb6fceaa48888629332e..08e94b3db7c5daee064eab94300e49c2326c8419 100644 (file)
@@ -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