make MusicBrainz queries thread-safe with a module-global lock

This commit is contained in:
Adrian Sampson 2010-07-29 11:47:19 -07:00
parent 0746fca7d7
commit 8f5aa3c594

View file

@ -20,10 +20,12 @@ syntax, and other uninteresting parts of using musicbrainz2. The
principal interface is the function `match_album`.
"""
from __future__ import with_statement # for Python 2.5
import re
import time
import datetime
import musicbrainz2.webservice as mbws
from threading import Lock
class ServerBusyError(Exception): pass
@ -34,6 +36,7 @@ class ServerBusyError(Exception): pass
MAX_QUERY_RETRY = 8
QUERY_WAIT_TIME = 1.0
last_query_time = 0.0
mb_lock = Lock()
def _query_wrap(fun, *args, **kwargs):
"""Wait until at least `QUERY_WAIT_TIME` seconds have passed since
the last invocation of this function. Then call
@ -41,25 +44,26 @@ def _query_wrap(fun, *args, **kwargs):
then try again. Tries up to `MAX_QUERY_RETRY` times before
giving up.
"""
global last_query_time
for i in range(MAX_QUERY_RETRY):
since_last_query = time.time() - last_query_time
if since_last_query < QUERY_WAIT_TIME:
time.sleep(QUERY_WAIT_TIME - since_last_query)
last_query_time = time.time()
try:
# Try the function.
res = fun(*args, **kwargs)
except mbws.WebServiceError, e:
# Server busy. Retry.
if 'Error 503' not in str(e.reason):
# This is not the error we're looking for.
raise
else:
# Success. Return the result.
return res
# Gave up.
raise ServerBusyError()
with mb_lock:
global last_query_time
for i in range(MAX_QUERY_RETRY):
since_last_query = time.time() - last_query_time
if since_last_query < QUERY_WAIT_TIME:
time.sleep(QUERY_WAIT_TIME - since_last_query)
last_query_time = time.time()
try:
# Try the function.
res = fun(*args, **kwargs)
except mbws.WebServiceError, e:
# Server busy. Retry.
if 'Error 503' not in str(e.reason):
# This is not the error we're looking for.
raise
else:
# Success. Return the result.
return res
# Gave up.
raise ServerBusyError()
# FIXME exponential backoff?
def _lucene_escape(text):