# HG changeset patch # User Jeff Hammel # Date 1350511189 25200 # Node ID fc5b842de4e91bb7a5f0a7d31a0ee8960fec80d1 # Parent cffb6f681b599605f5557a94bbebab8807f04f18 be a little less aggressive when caching diff -r cffb6f681b59 -r fc5b842de4e9 dogdish/dispatcher.py --- a/dogdish/dispatcher.py Wed Oct 17 13:26:22 2012 -0700 +++ b/dogdish/dispatcher.py Wed Oct 17 14:59:49 2012 -0700 @@ -16,6 +16,7 @@ here = os.path.dirname(os.path.abspath(__file__)) +### models class Application(object): """class for storing application.ini data""" @@ -29,6 +30,53 @@ self.build_id = config.get('App', 'BuildID') self.version = config.get('App', 'Version') + +class Update(object): + """class representing a .mar update file""" + + prefix = 'b2g_update_' + suffix = '.mar' + + @classmethod + def updates(cls, directory): + """returns the updates in a directory""" + + contents = [i for i in os.listdir(directory) + if i.startswith(cls.prefix) and i.endswith(cls.suffix)] + contents = set(contents) + return contents + + def __init__(self, directory, filename): + self.directory = directory + self.filename = filename + self.path = os.path.join(directory, filename) + self.stamp = filename[len(self.prefix):-len(self.suffix)] + self.size = os.path.getsize(self.path) + + # cached properties + self._application = None + self._hash = None + + def application(self): + """ + returns the path to the application.ini + associated with this update + """ + + if not self._application: + application_ini = 'application_%s.ini' % self.stamp + application_ini = os.path.join(self.directory, application_ini) + assert os.path.exists(application_ini) + self._application = Application(application_ini) + return self._application + + def hash(self): + if not self._hash: + # compute the hash + with file(self.path) as f: + self._hash = hashlib.sha512(f.read()).hexdigest() + return self._hash + ### request handlers class Handler(object): @@ -72,13 +120,13 @@ def __call__(self): - update_path = os.path.join(self.app.directory, self.app.current_update) body = self.body query = {} dogfood_id = self.request.GET.get('dogfood_id') if dogfood_id: query['dogfooding_prerelease_id'] = dogfood_id - application = self.app.updates[self.app.current_update] + current_update = self.app.current_update + application = current_update.application() query['build_id'] = application.build_id query['version'] = application.version @@ -88,14 +136,11 @@ else: query = '' - # compute the hash - with file(update_path) as f: - sha512 = hashlib.sha512(f.read()).hexdigest() # template variables - variables = dict(update=self.app.current_update, - size=os.path.getsize(update_path), - hash=sha512, + variables = dict(update=current_update.filename, + size=current_update.size, + hash=current_update.hash(), query=query) return Response(content_type='text/xml', @@ -118,8 +163,6 @@ # cache self.updates = {} self.current_update = None - self.current_stamp = '0000-00-00_000000' - self.cached_response = None # scan directory self.scan() @@ -130,13 +173,10 @@ request = Request(environ) new = self.scan() - if (not new) and (self.cached_response is not None): - return self.cached_response(environ, start_response) for h in self.handlers: if h.match(request): handler = h(self, request) res = handler() - self.cached_response = res break else: res = exc.HTTPNotFound() @@ -148,25 +188,21 @@ scan the directory for updates returns True if new updates are found, False otherwise """ - prefix = 'b2g_update_' - suffix = '.mar' - contents = [i for i in os.listdir(self.directory) - if i.startswith(prefix) and i.endswith(suffix)] - contents = set(contents) + + # check for new updates + contents = Update.updates(self.directory) new = contents.difference(self.updates.keys()) if not new: # directory contents unchanged from cached values return False for update in new: - stamp = update[len(prefix):-len(suffix)] - application_ini = 'application_%s.ini' % stamp - application_ini = os.path.join(self.directory, application_ini) - assert os.path.exists(application_ini) - self.updates[update] = Application(application_ini) - if stamp > self.current_stamp: - self.current_update = update - self.current_stamp = stamp + self.updates[update] = Update(self.directory, update) + if self.current_update: + if self.updates[update].stamp > self.current_update.stamp: + self.current_update = self.updates[update] + else: + self.current_update = self.updates[update] # TODO: could remove old files from the cache if not found in contents