def handle_request(layer_id, redis_conn): '''handler for any item pulled from worker job queue This handler is called every time the worker is able to pop a message from the job queue filled by the registry. The worker blocks until a message is available. This handler will then attempt to aquire a lock for the provided layer_id and if successful, process a diff for the layer. If the lock for this layer_id has already been aquired for this layer the worker will immediately timeout to block for another request. ''' try: # this with-context will attempt to establish a 5 minute lock # on the key for this layer, immediately passing on LockTimeout # if one isn't availble with rlock.Lock(redis_conn, "diff-worker-lock", layer_id, expires=60 * 5): # first check if a cached result is already available. The registry # already does this, but hey. diff_data = layers.get_image_diff_cache(layer_id) if not diff_data: log.info("Processing diff for %s" % layer_id) layers.get_image_diff_json(layer_id) except rlock.LockTimeout: log.info("Another worker is processing %s. Skipping." % layer_id)
def test_image_diff_json(self): layer_1 = ( ("deleted", "f", False, 512, 0, 420, 0, 0), ("changed", "f", False, 512, 0, 420, 0, 0), ) layer_2 = ( ("deleted", "f", True, 512, 0, 420, 0, 0), ("changed", "f", False, 512, 0, 420, 0, 0), ("created", "f", False, 512, 0, 420, 0, 0), ) layer_1_id = rndstr(16) layer_2_id = rndstr(16) ancestry = json.dumps([layer_2_id, layer_1_id]) ancestry_path = self.store.image_ancestry_path(layer_2_id) self.store.put_content(ancestry_path, ancestry) layer_1_files_path = self.store.image_files_path(layer_1_id) self.store.put_content(layer_1_files_path, json.dumps(layer_1)) layer_2_files_path = self.store.image_files_path(layer_2_id) self.store.put_content(layer_2_files_path, json.dumps(layer_2)) diff_json = layers.get_image_diff_json(layer_2_id) diff = json.loads(diff_json) for type in ("deleted", "changed", "created"): self.assertIn(type, diff) self.assertIn(type, diff[type])