Revision: 292
Author: bslatkin
Date: Mon Oct 26 09:47:02 2009
Log: added subscription clean-up handler
http://code.google.com/p/pubsubhubbub/source/detail?r=292

Modified:
 /trunk/hub/cron.yaml
 /trunk/hub/main.py
 /trunk/hub/main_test.py

=======================================
--- /trunk/hub/cron.yaml        Thu Aug 20 00:51:07 2009
+++ /trunk/hub/cron.yaml        Mon Oct 26 09:47:02 2009
@@ -7,6 +7,10 @@
   url: /work/event_cleanup
   schedule: every 1 minutes

+- description: Subscription cleanup
+  url: /work/subscription_cleanup
+  schedule: every 1 minutes
+
 - description: Subscription reconfirmation
   url: /work/reconfirm_subscriptions
   schedule: every 3 hours
=======================================
--- /trunk/hub/main.py  Mon Oct 26 09:29:16 2009
+++ /trunk/hub/main.py  Mon Oct 26 09:47:02 2009
@@ -163,6 +163,9 @@
# How many completely failed EventToDeliver instances to clean up at a time.
 EVENT_CLEANUP_CHUNK_SIZE = 50

+# How many old Subscription instances to clean up at a time.
+SUBSCRIPTION_CLEANUP_CHUNK_SIZE = 100
+
 # How far before expiration to refresh subscriptions.
 SUBSCRIPTION_CHECK_BUFFER_SECONDS = (24 * 60 * 60)  # 24 hours

@@ -1830,6 +1833,22 @@
         sub.request_insert(sub.callback, sub.topic, sub.verify_token,
                            sub.secret, auto_reconfirm=True)

+
+class SubscriptionCleanupHandler(webapp.RequestHandler):
+  """Background worker for cleaning up deleted Subscription instances."""
+
+  @work_queue_only
+  def get(self):
+    subscriptions = (Subscription.all()
+              .filter('subscription_state =', Subscription.STATE_TO_DELETE)
+              .fetch(SUBSCRIPTION_CLEANUP_CHUNK_SIZE))
+    if subscriptions:
+      logging.info('Cleaning up %d subscriptions', len(subscriptions))
+      try:
+        db.delete(subscriptions)
+ except (db.Error, apiproxy_errors.Error, runtime.DeadlineExceededError):
+        logging.exception('Could not clean-up Subscription instances')
+
################################################################################
 # Publishing handlers

@@ -2887,6 +2906,7 @@
       # Periodic workers
       (r'/work/poll_bootstrap', PollBootstrapHandler),
       (r'/work/event_cleanup', EventCleanupHandler),
+      (r'/work/subscription_cleanup', SubscriptionCleanupHandler),
       (r'/work/reconfirm_subscriptions', SubscriptionReconfirmHandler)
     ])
   application = webapp.WSGIApplication(HANDLERS, debug=DEBUG)
=======================================
--- /trunk/hub/main_test.py     Mon Oct 26 09:29:16 2009
+++ /trunk/hub/main_test.py     Mon Oct 26 09:47:02 2009
@@ -3350,6 +3350,31 @@
         t['params']['subscription_key_name'] for t in confirm_tasks]
     self.assertEquals(confirm_key_names, found_key_names)

+
+class SubscriptionCleanupHandlerTest(testutil.HandlerTestBase):
+  """Tests fo the SubscriptionCleanupHandler."""
+
+  handler_class = main.SubscriptionCleanupHandler
+
+  def testEmpty(self):
+    """Tests cleaning up empty subscriptions."""
+    self.handle('get')
+
+  def testCleanup(self):
+    """Tests cleaning up a few deleted subscriptions."""
+    callback = 'http://example.com/callback/%d'
+    topic = 'http://example.com/mytopic'
+    self.assertTrue(Subscription.insert(callback % 1, topic, '', ''))
+    self.assertTrue(Subscription.insert(callback % 2, topic, '', ''))
+    self.assertTrue(Subscription.insert(callback % 3, topic, '', ''))
+    self.assertEquals(3 * [Subscription.STATE_VERIFIED],
+                      [s.subscription_state for s in Subscription.all()])
+
+    Subscription.archive(callback % 1, topic)
+    self.handle('get')
+    self.assertEquals(2 * [Subscription.STATE_VERIFIED],
+                      [s.subscription_state for s in Subscription.all()])
+
################################################################################

 PollingMarker = main.PollingMarker

Reply via email to