Revision: 362
Author: bslatkin
Date: Thu Jun  3 16:30:46 2010
Log: hub will treat DB errors are fetch/parse retries, do backoff
http://code.google.com/p/pubsubhubbub/source/detail?r=362

Modified:
 /trunk/hub/main.py

=======================================
--- /trunk/hub/main.py  Thu Jun  3 16:20:53 2010
+++ /trunk/hub/main.py  Thu Jun  3 16:30:46 2010
@@ -2392,7 +2392,7 @@
   pass


-def parse_feed(feed_record, headers, content):
+def parse_feed(feed_record, headers, content, true_on_bad_feed=True):
   """Parses a feed's content, determines changes, enqueues notifications.

This function will only enqueue new notifications if the feed has changed.
@@ -2402,6 +2402,10 @@
     headers: Dictionary of response headers found during feed fetching (may
         be empty).
     content: The feed document possibly containing new entries.
+    true_on_bad_feed: When True, return True when the feed's format is
+      beyond hope and there's no chance of parsing it correctly. When
+      False the error will be propagated up to the caller with a False
+      response to this function.

   Returns:
     True if successfully parsed the feed content; False on error.
@@ -2437,13 +2441,13 @@
                       feed_record.topic, error_traceback)
# Yes-- returning True here. This feed is beyond all hope because we just
       # don't support this character encoding presently.
-      return True
+      return true_on_bad_feed

   if parse_failures == len(order):
     logging.error('Could not parse feed; giving up:\n%s', error_traceback)
     # That's right, we return True. This will cause the fetch to be
     # abandoned on parse failures because the feed is beyond hope!
-    return True
+    return true_on_bad_feed

# If we have more entities than we'd like to handle, only save a subset of
   # them and force this task to retry as if it failed. This will cause two
@@ -2500,16 +2504,24 @@
     if event_to_deliver:
       event_to_deliver.enqueue()

-  for i in xrange(PUT_SPLITTING_ATTEMPTS):
-    try:
-      db.run_in_transaction(txn)
-      break
-    except (db.BadRequestError, apiproxy_errors.RequestTooLargeError):
-      pass
-  else:
- logging.critical('Insertion of event to delivery *still* failing due to ' - 'request size; dropping event for %s', feed_record.topic)
-    return True
+  try:
+    for i in xrange(PUT_SPLITTING_ATTEMPTS):
+      try:
+        db.run_in_transaction(txn)
+        break
+      except (db.BadRequestError, apiproxy_errors.RequestTooLargeError):
+        pass
+    else:
+ logging.critical('Insertion of event to delivery *still* failing due to ' + 'request size; dropping event for %s', feed_record.topic)
+      return true_on_bad_feed
+  except (db.TransactionFailedError, db.Timeout):
+    # Datastore failure will cause a refetch and reparse of the feed as if
+    # the fetch attempt failed, instead of relying on the task queue to do
+ # this retry for us. This ensures the queue throughputs stay consistent.
+    logging.exception('Could not submit transaction for topic %r',
+                      feed_record.topic)
+    return False

   # Inform any hooks that there will is a new event to deliver that has
   # been recorded and delivery has begun.

Reply via email to