def _reserve_resource(resource_id): """ When you wish you queue a task that needs to reserve a resource, you should make a call to this function() first, queueing it in the RESOURCE_MANAGER_QUEUE. This Task will return the name of the queue you should put your task in. Please be sure to also add a task to run _queue_release_resource() in the same queue name that this function returns to you. It is important that _release_resource() is called after your task is completed, regardless of whether your task completes successfully or not. :param resource_id: The name of the resource you wish to reserve for your task. The system will ensure that no other tasks that want that same reservation will run concurrently with yours. :type resource_id: basestring :return: The name of a queue that you should put your task in :rtype: basestring """ reserved_resource = resources.get_or_create_reserved_resource(resource_id) if reserved_resource.assigned_queue is None: # The assigned_queue will be None if the reserved_resource was just created, so we'll # need to assign a queue to it reserved_resource.assigned_queue = resources.get_least_busy_available_queue().name reserved_resource.save() else: # The assigned_queue is set, so we just need to increment the num_reservations on the # reserved resource reserved_resource.increment_num_reservations() AvailableQueue(reserved_resource.assigned_queue).increment_num_reservations() return reserved_resource.assigned_queue
def _reserve_resource(resource_id): """ When you wish you queue a task that needs to reserve a resource, you should make a call to this function() first, queueing it in the RESOURCE_MANAGER_QUEUE. This Task will return the name of the queue you should put your task in. Please be sure to also add a task to run _queue_release_resource() in the same queue name that this function returns to you. It is important that _release_resource() is called after your task is completed, regardless of whether your task completes successfully or not. :param resource_id: The name of the resource you wish to reserve for your task. The system will ensure that no other tasks that want that same reservation will run concurrently with yours. :type resource_id: basestring :return: The name of a queue that you should put your task in :rtype: basestring """ reserved_resource = resources.get_or_create_reserved_resource(resource_id) if reserved_resource.assigned_queue is None: # The assigned_queue will be None if the reserved_resource was just created, so we'll # need to assign a queue to it # get the dedicated queue name by adding '.dq' to the end of the worker name reserved_resource.assigned_queue = resources.get_least_busy_available_queue().name + '.dq' reserved_resource.save() else: # The assigned_queue is set, so we just need to increment the num_reservations on the # reserved resource reserved_resource.increment_num_reservations() # Remove the '.dq' from the queue name to get the worker name worker_name = reserved_resource.assigned_queue.rstrip('.dq') aqc = Criteria(filters={'_id': worker_name}) aq_list = list(resources.filter_available_queues(aqc)) aq_list[0].increment_num_reservations() return reserved_resource.assigned_queue
def test_picks_least_busy_queue(self): """ Test that the function picks the least busy queue. """ # Set up three available queues, with the least busy one in the middle so that we can # demonstrate that it did pick the least busy and not the last or first. available_queue_1 = AvailableQueue('busy_queue', 7) available_queue_1.save() available_queue_2 = AvailableQueue('less_busy_queue', 3) available_queue_2.save() available_queue_3 = AvailableQueue('most_busy_queue', 10) available_queue_3.save() queue = resources.get_least_busy_available_queue() self.assertEqual(type(queue), AvailableQueue) self.assertEqual(queue.num_reservations, 3) self.assertEqual(queue.name, 'less_busy_queue')