Skip to content

Commit

Permalink
clear cached webmention endpoints when retrying
Browse files Browse the repository at this point in the history
  • Loading branch information
snarfed committed Oct 27, 2015
1 parent 54b4bf8 commit d6661a6
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
5 changes: 5 additions & 0 deletions app.py
Expand Up @@ -38,6 +38,7 @@
import twitter
import wordpress_rest

from google.appengine.api import memcache
from google.appengine.ext import ndb
from google.appengine.ext.ndb.stats import KindStat, KindPropertyNameStat
import webapp2
Expand Down Expand Up @@ -487,6 +488,10 @@ def post(self):
entity.sent = entity.skipped = []
entity.put()

# clear any cached webmention endpoints
memcache.delete_multi(util.webmention_endpoint_cache_key(url) for url in
entity.unsent + entity.error + entity.failed)

if entity.key.kind() == 'Response':
util.add_propagate_task(entity)
elif entity.key.kind() == 'BlogPost':
Expand Down
7 changes: 2 additions & 5 deletions tasks.py
Expand Up @@ -486,13 +486,10 @@ def do_send_webmentions(self):
# see if we've cached webmention discovery for this domain. the cache
# value is a string URL endpoint if discovery succeeded, a
# WebmentionSend error dict if it failed (semi-)permanently, or None.
domain = util.domain_from_link(target)
scheme = urlparse.urlparse(target).scheme
cache_key = ' '.join(('W', scheme, domain))
cache_key = util.webmention_endpoint_cache_key(target)
cached = memcache.get(cache_key)
if cached:
logging.info('Using cached webmention endpoint for %s %s: %s',
scheme, domain, cached)
logging.info('Using cached webmention endpoint %r: %s', cache_key, cached)

# send! and handle response or error
error = None
Expand Down
15 changes: 13 additions & 2 deletions test/test_app.py
Expand Up @@ -3,6 +3,7 @@
import datetime
import urllib

from google.appengine.api import memcache
from google.appengine.ext import ndb
from oauth_dropins import handlers as oauth_handlers
import mf2py
Expand Down Expand Up @@ -35,10 +36,14 @@ def test_poll_now(self):
def test_retry_response(self):
self.assertEqual([], self.taskqueue_stub.GetTasks('propagate'))

self.responses[0].status = 'complete'
self.responses[0].sent = ['http://sent']
self.responses[0].skipped = ['http://skipped']
self.responses[0].skipped = ['https://skipped']
self.responses[0].put()

# cached webmention endpoint
memcache.set('W https skipped', 'asdf')

key = self.responses[0].key.urlsafe()
resp = app.application.get_response(
'/retry', method='POST', body='key=' + key)
Expand All @@ -48,12 +53,18 @@ def test_retry_response(self):
params = testutil.get_task_params(self.taskqueue_stub.GetTasks('propagate')[0])
self.assertEqual(key, params['response_key'])

# status and URLs should be refreshed
got = self.responses[0].key.get()
self.assertEqual('new', got.status)
self.assertItemsEqual(
['http://sent', 'http://skipped', 'http://target1/post/url'], got.unsent)
['http://sent', 'https://skipped', 'http://target1/post/url'], got.unsent)
self.assertEqual([], got.sent)
self.assertEqual([], got.skipped)

# webmention endpoints for URL domains should be refreshed
self.assertIsNone(memcache.get('W https skipped'))


def test_poll_now_and_retry_response_missing_key(self):
for endpoint in '/poll-now', '/retry':
for body in '', 'key=' + self.responses[0].key.urlsafe(): # hasn't been stored
Expand Down
10 changes: 10 additions & 0 deletions util.py
Expand Up @@ -115,6 +115,16 @@ def add_propagate_blogpost_task(entity, **kwargs):
logging.info('Added propagate-blogpost task: %s', task.name)


def webmention_endpoint_cache_key(url):
"""Returns memcache key for a cached webmention endpoint for a given URL.
Example: 'W https snarfed.org'
"""
domain = util.domain_from_link(url)
scheme = urlparse.urlparse(url).scheme
return ' '.join(('W', scheme, domain))


def email_me(**kwargs):
"""Thin wrapper around mail.send_mail() that handles errors."""
try:
Expand Down

0 comments on commit d6661a6

Please sign in to comment.