Example #1
0
class Agent(object):
    """
    Agent class presents an instance of agent application.
    """

    def __init__(self, afm_url, default_wait=60, max_tasks=2, name='Python Agent 1.0', agent_uuid=None):

        self.afm = Communicator(afm_url)
        self.max_tasks = max_tasks
        self.default_wait = default_wait
        self.name = name
        self.uuid = agent_uuid if agent_uuid else str(uuid.uuid1())
        self._run = True

    def exit(self):
        """
        Signal agent to exit. After issuing exit, agent will not make further task requests,
        but will wait until all currently processed tasks finish.
        """
        self._run = False

    def run(self):
        """
        The "main function" of the agent, looping the claim & execute tasks flow.
        """

        with Executor(self.max_tasks) as executor:
            while self._run:

                wait_time = self.default_wait
                min_wait_time = 1

                # request for tasks
                try:
                    task_response = self.afm.request_tasks(
                        agent_id=self.uuid,
                        agent_name=self.name,
                        agent_time=timeutil.format(timeutil.now()),
                        agent_capabilities=TaskHandler.list_all(),
                        max_tasks=executor.available_executors()
                    )
                    if 'tasks' in task_response:
                        for task_data in task_response['tasks']:
                            executor.submit_task(task_data,
                                                 lambda *args, **kwargs: self.afm.post_result(*args, **kwargs))
                    if 'return_time' in task_response:
                        return_time = timeutil.parse(task_response['return_time'])
                        wait_time = max(min_wait_time, (return_time - timeutil.now()).total_seconds())
                except TemporaryError as e:
                    logging.getLogger("Agent").error("An error occurred while claiming tasks: %s", e)

                time.sleep(wait_time)
Example #2
0
    def __init__(self,
                 afm_url,
                 default_wait=60,
                 max_tasks=2,
                 name='Python Agent 1.0',
                 agent_uuid=None):

        self.afm = Communicator(afm_url)
        self.max_tasks = max_tasks
        self.default_wait = default_wait
        self.name = name
        self.uuid = agent_uuid if agent_uuid else str(uuid.uuid1())
        self._run = True
Example #3
0
    def __init__(self, afm_url, default_wait=60, max_tasks=2, name='Python Agent 1.0', agent_uuid=None):

        self.afm = Communicator(afm_url)
        self.max_tasks = max_tasks
        self.default_wait = default_wait
        self.name = name
        self.uuid = agent_uuid if agent_uuid else str(uuid.uuid1())
        self._run = True
Example #4
0
class Agent(object):
    """
    Agent class presents an instance of agent application.
    """
    def __init__(self,
                 afm_url,
                 default_wait=60,
                 max_tasks=2,
                 name='Python Agent 1.0',
                 agent_uuid=None):

        self.afm = Communicator(afm_url)
        self.max_tasks = max_tasks
        self.default_wait = default_wait
        self.name = name
        self.uuid = agent_uuid if agent_uuid else str(uuid.uuid1())
        self._run = True

    def exit(self):
        """
        Signal agent to exit. After issuing exit, agent will not make further task requests,
        but will wait until all currently processed tasks finish.
        """
        self._run = False

    def run(self):
        """
        The "main function" of the agent, looping the claim & execute tasks flow.
        """

        with Executor(self.max_tasks) as executor:
            while self._run:

                wait_time = self.default_wait
                min_wait_time = 1

                # request for tasks
                try:
                    task_response = self.afm.request_tasks(
                        agent_id=self.uuid,
                        agent_name=self.name,
                        agent_time=timeutil.format(timeutil.now()),
                        agent_capabilities=TaskHandler.list_all(),
                        max_tasks=executor.available_executors())
                    if 'tasks' in task_response:
                        for task_data in task_response['tasks']:
                            executor.submit_task(
                                task_data,
                                lambda *args, **kwargs: self.afm.post_result(
                                    *args, **kwargs))
                    if 'return_time' in task_response:
                        return_time = timeutil.parse(
                            task_response['return_time'])
                        wait_time = max(min_wait_time,
                                        (return_time -
                                         timeutil.now()).total_seconds())
                except TemporaryError as e:
                    logging.getLogger("Agent").error(
                        "An error occurred while claiming tasks: %s", e)

                time.sleep(wait_time)
Example #5
0
 def setUp(self):
     self.communicator = Communicator('https://localhost')
Example #6
0
class CommunicatorTests(unittest.TestCase):
    def setUp(self):
        self.communicator = Communicator('https://localhost')

    @responses.activate
    def test_server_error(self):
        _add_responses(status=500)
        with self.assertRaises(TemporaryError):
            self.communicator.request_tasks()

    @responses.activate
    def test_client_error(self):
        _add_responses(status=400)
        with self.assertRaises(FatalError):
            self.communicator.request_tasks()

    @responses.activate
    def test_json_error(self):
        _add_responses(body="[asd")
        with self.assertRaises(FatalError):
            self.communicator.request_tasks()

    @responses.activate
    def test_connection_error(self):
        _add_responses(url='https://localhost2/tasks')
        with self.assertRaises(TemporaryError):
            self.communicator.request_tasks()

    @responses.activate
    def test_valid_json(self):
        _add_responses(body=json.dumps({
            "tasks": [{
                "task_id": "123e4567-e89b-12d3-a456-426655440000",
                "task_type": "wait",
                "task_version": 1,
                "task_data": {
                    "time": "1"
                }
            }],
            "return_time":
            "2012-04-23T18:25:43.511Z"
        }))
        self.assertIsInstance(self.communicator.request_tasks(), dict)

    @responses.activate
    def test_result_retries(self):
        class CountResponses(object):
            def __init__(self):
                self.counter = 0

            def __call__(self, request):
                self.counter += 1
                assert self.counter <= 2, 'Agent should stop retrying after OK response!'
                if self.counter < 2:
                    return 500, {}, None
                else:
                    return 200, {}, None

        responses.add_callback(responses.POST,
                               'https://localhost/tasks/response',
                               callback=CountResponses(),
                               content_type='application/json')

        self.communicator.post_result('task-id', task_data={})
        self.assertEqual(
            len(responses.calls), 2,
            'Agent should retry result upload on temporary error!')
Example #7
0
 def setUp(self):
     self.communicator = Communicator('https://localhost')
Example #8
0
class CommunicatorTests(unittest.TestCase):
    def setUp(self):
        self.communicator = Communicator('https://localhost')

    @responses.activate
    def test_server_error(self):
        _add_responses(status=500)
        with self.assertRaises(TemporaryError):
            self.communicator.request_tasks()

    @responses.activate
    def test_client_error(self):
        _add_responses(status=400)
        with self.assertRaises(FatalError):
            self.communicator.request_tasks()

    @responses.activate
    def test_json_error(self):
        _add_responses(body="[asd")
        with self.assertRaises(FatalError):
            self.communicator.request_tasks()

    @responses.activate
    def test_connection_error(self):
        _add_responses(url='https://localhost2/tasks')
        with self.assertRaises(TemporaryError):
            self.communicator.request_tasks()

    @responses.activate
    def test_valid_json(self):
        _add_responses(
            body=json.dumps({
                "tasks": [
                    {
                        "task_id": "123e4567-e89b-12d3-a456-426655440000",
                        "task_type": "wait",
                        "task_version": 1,
                        "task_data": {
                            "time": "1"
                        }
                    }
                ],
                "return_time": "2012-04-23T18:25:43.511Z"
            })
        )
        self.assertIsInstance(self.communicator.request_tasks(), dict)

    @responses.activate
    def test_result_retries(self):
        class CountResponses(object):
            def __init__(self):
                self.counter = 0

            def __call__(self, request):
                self.counter += 1
                assert self.counter <= 2, 'Agent should stop retrying after OK response!'
                if self.counter < 2:
                    return 500, {}, None
                else:
                    return 200, {}, None

        responses.add_callback(
            responses.POST, 'https://localhost/tasks/response',
            callback=CountResponses(),
            content_type='application/json'
        )

        self.communicator.post_result('task-id', task_data={})
        self.assertEqual(len(responses.calls), 2, 'Agent should retry result upload on temporary error!')