Do transforms on tag changes instead of on ITEMS
authorJack Miller <jack@codezen.org>
Mon, 15 Jun 2015 21:08:10 +0000 (16:08 -0500)
committerJack Miller <jack@codezen.org>
Tue, 16 Jun 2015 06:21:58 +0000 (01:21 -0500)
canto_next/canto_backend.py
canto_next/hooks.py
canto_next/tag.py

index 6b00cb1..603608a 100644 (file)
@@ -250,38 +250,6 @@ class CantoBackend(PluginHandler, CantoServer):
         on_hook("daemon_del_configs", lambda x, y : self.internal_command(x, self.in_delconfigs, y))
         on_hook("daemon_get_configs", lambda x, y : self.internal_command(x, self.in_configs, y))
 
-    # Return list of item tuples after global transforms have been performed on
-    # them.
-
-    @read_lock(config_lock)
-    @read_lock(socktran_lock)
-    @read_lock(feed_lock)
-    @read_lock(tag_lock)
-    def apply_transforms(self, socket, tag):
-        tagobj = alltags.get_tag(tag)
-
-        feeds = allfeeds.items_to_feeds(tagobj)
-        rlock_feed_objs(feeds)
-
-        try:
-            # Global transform
-            if config.global_transform:
-                tagobj = config.global_transform(tagobj)
-
-            # Tag level transform
-            if tag in alltags.tag_transforms and\
-                    alltags.tag_transforms[tag]:
-                tagobj = alltags.tag_transforms[tag](tagobj)
-
-            # Socket transforms ANDed together.
-            if socket in self.socket_transforms:
-                for filt in self.socket_transforms[socket]:
-                    tagobj = self.socket_transforms[socket][filt](tagobj)
-        finally:
-            runlock_feed_objs(feeds)
-
-        return tagobj
-
     # VERSION -> X.Y
 
     def cmd_version(self, socket, args):
@@ -378,16 +346,28 @@ class CantoBackend(PluginHandler, CantoServer):
 
     # ITEMS [tags] -> { tag : [ ids ], tag2 : ... }
 
+    @read_lock(feed_lock)
+    def _apply_socktrans(self, socket, tag):
+        feeds = allfeeds.items_to_feeds(tag)
+        rlock_feed_objs(feeds)
+        try:
+            for filt in self.socket_transforms[socket]:
+                tag = self.socket_transforms[socket][filt](tag)
+        finally:
+            runlock_feed_objs(feeds)
+        return tag
+
     @read_lock(attr_lock)
+    @read_lock(socktran_lock)
     def cmd_items(self, socket, args):
         ids = []
         response = {}
 
         for tag in args:
-            # get_tag returns a list invariably, but may be empty.
-            items = self.apply_transforms(socket, tag)
+            items = alltags.get_tag(tag)
 
-            # Divide each response into 100 items or less and dispatch them
+            if socket in self.socket_transforms:
+                items = self._apply_socktrans(socket, items)
 
             attr_list = []
 
index 74bf271..b3d28cb 100644 (file)
@@ -41,7 +41,6 @@ def unhook_all(key):
 
 def call_hook(hook, args):
     if hook in hooks:
-
         # List copy here so hooks can remove themselves
         # without effecting our iteration.
 
index ecec6ce..47feeda 100644 (file)
@@ -6,7 +6,8 @@
 #   published by the Free Software Foundation.
 
 from .hooks import on_hook, call_hook
-from .locks import tag_lock
+from .rwlock import read_lock, write_lock
+from .locks import *
 
 import logging
 
@@ -79,6 +80,8 @@ class CantoTags():
         else:
             extras = []
 
+        log.debug("EXTRAS: %s")
+
         alladded = [ name ] + extras
 
         for name in alladded:
@@ -103,15 +106,40 @@ class CantoTags():
                 self.tags[tag].remove(id)
                 self.tag_changed(tag)
 
+    def apply_transforms(self, tag, tagobj):
+        from .config import config
+        # Global transform
+        if config.global_transform:
+            tagobj = config.global_transform(tagobj)
+
+        # Tag level transform
+        if tag in self.tag_transforms and\
+                self.tag_transforms[tag]:
+            tagobj = self.tag_transforms[tag](tagobj)
+
+        return tagobj
+
     #
     # This is called from a hook, so it has to get the lock itself
     #
 
+    @read_lock(config_lock)
+    @read_lock(feed_lock)
+    @write_lock(tag_lock)
     def do_tag_changes(self):
-        tag_lock.acquire_write()
+        from .feed import allfeeds, rlock_feed_objs, runlock_feed_objs
         for tag in self.changed_tags:
+            tagobj = self.get_tag(tag)
+
+            feeds = allfeeds.items_to_feeds(tagobj)
+            rlock_feed_objs(feeds)
+            try:
+                tagobj = self.apply_transforms(tag, tagobj)
+            finally:
+                runlock_feed_objs(feeds)
+
+            self.tags[tag] = tagobj
             call_hook("daemon_tag_change", [ tag ])
         self.changed_tags = []
-        tag_lock.release_write()
 
 alltags = CantoTags()