Skip to content
Snippets Groups Projects
Commit 243f71de authored by Sybren A. Stüvel's avatar Sybren A. Stüvel
Browse files

Worker: discard task updates when task is assigned to another worker

The Manager will return a 409 Conflict status for updates to tasks that
have been assigned to another worker. This change prevents the worker
from trying to push these updates indefinitely to the Manager.
parent 2c4f80af
No related branches found
Tags v2.0-beta10
No related merge requests found
...@@ -126,8 +126,14 @@ class TaskUpdateQueue: ...@@ -126,8 +126,14 @@ class TaskUpdateQueue:
self._log.info('Pushing task update to Manager') self._log.info('Pushing task update to Manager')
resp = await self.manager.post(url, json=payload, loop=loop) resp = await self.manager.post(url, json=payload, loop=loop)
resp.raise_for_status() if resp.status_code == 409:
self._log.debug('Master accepted pushed update.') # The task was assigned to another worker, so we're not allowed to
# push updates for it. We have to un-queue this update, as it will
# never be accepted.
self._log.warning('Task was assigned to another worker, discarding update.')
else:
resp.raise_for_status()
self._log.debug('Master accepted pushed update.')
self._unqueue(rowid) self._unqueue(rowid)
if queue_is_empty: if queue_is_empty:
......
...@@ -147,3 +147,39 @@ class TaskUpdateQueueTest(AbstractWorkerTest): ...@@ -147,3 +147,39 @@ class TaskUpdateQueueTest(AbstractWorkerTest):
self.assertEqual(received_url, '/push/there') self.assertEqual(received_url, '/push/there')
self.assertEqual(received_payload, payload) self.assertEqual(received_payload, payload)
self.assertEqual(received_loop, self.asyncio_loop) self.assertEqual(received_loop, self.asyncio_loop)
def test_conflict(self):
"""A 409 Conflict response should discard a queued task update.
"""
from mock_responses import JsonResponse, EmptyResponse
# Try different value types
payload = {'key': 'value',
'sub': {'some': 13,
'values': datetime.datetime.now()}}
tries = 0
async def push_callback(url, *, json, loop):
nonlocal tries
tries += 1
self.shutdown_future.cancel()
return JsonResponse({}, status_code=409)
self.manager.post.side_effect = push_callback
self.tuqueue.queue('/push/here', payload, loop=self.asyncio_loop)
# Run the loop for 2 seconds. This should be enough for 3 retries of 0.3 seconds + handling
# the actual payload.
self.asyncio_loop.run_until_complete(
asyncio.wait_for(
self.tuqueue.work(loop=self.asyncio_loop),
timeout=2
)
)
# There should only be one attempt at delivering this payload.
self.assertEqual(1, tries)
self.assertEqual([], list(self.tuqueue._queue()))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment