Example #1
0
    def exec_async(self, *args, **kwargs):
        if self.task_id:
            task_id = self.task_id
        else:
            task_id = uuid1()
        print self.func
        args_json = json.dumps(getcallargs(self.func, *args, **kwargs), indent=2)

        redis = create_redis_connection(self.redis_connection)

        task_hash_key = get_task_hash_key(task_id)
        pending_list_key = get_pending_list_key(self.queue)
        results_channel_key = get_results_channel_key()

        pubsub = redis.pubsub(ignore_subscribe_messages=True)
        pubsub.subscribe(results_channel_key)

        pipe = redis.pipeline(transaction=True)

        pipe.lpush(pending_list_key, task_id)

        print self.virtual_memory_limit

        pipe.hmset(task_hash_key,
                   {TASK_HKEY_FUNCTION: self.func.__name__,
                   TASK_HKEY_ARGS: args_json,
                   TASK_HKEY_STATE: STATE_PENDING,
                   TASK_HKEY_USERNAME: self.username,
                   TASK_HKEY_PENDING_CREATED: json.strftime(datetime.utcnow()),
                   TASK_HKEY_VIRTUAL_MEMORY_LIMIT: self.virtual_memory_limit})

        pipe.execute()

        return AsyncResult(redis, pubsub, task_hash_key, task_id)
Example #2
0
def _set_task_finished_with_timeout(
                  queue,
                  task_id,
                  task_hash_key,
                  result=True,
                  result_value=None,
                  error_reason=None,
                  error_exception=None,
                  logger=None,
                  timeout=6):

    redis = create_redis_connection(timeout=timeout)
    _set_task_finished_no_blocking(redis,
                                   queue,
                                   task_id,
                                   task_hash_key,
                                   result,
                                   result_value,
                                   error_reason,
                                   error_exception,
                                   logger=logger)
Example #3
0
def _deregister_worker_with_timeout(worker_uuid, timeout=2):
    redis = create_redis_connection(timeout=timeout)
    redis.delete(get_worker_hash_key(worker_uuid))
Example #4
0
def worker_server(module, queue):

    worker_uuid = uuid4()
    redis = create_redis_connection()

    logger = _create_logger()
    logger.info('worker:{0} pid: {1} started'.format(worker_uuid, os.getpid()))

    cmd_pubsub = _subscribe_to_cmd_pubsub(redis)

    _register_worker(redis, worker_uuid)

    task_id = None
    task_hash_key = None
    process = None
    try:
        while not _terminate.is_set():
            task_id = _get_next_task_id(redis, queue, timeout=1)
            # if task_id is None we got a timeout
            if task_id is None:
                continue

            task_hash_key = get_task_hash_key(task_id)

            print task_hash_key
            logger.info('wtf')
            process = Process(target=_exexcute_task,
                              args=(module, queue, task_id, task_hash_key))
            terminated = False
            killed = False
            process.start()

            while process.is_alive() and not _terminate.is_set():
                process.join(0.2)

                if _poll_kill_task(cmd_pubsub, task_hash_key):
                    killed = True
                    break

            if _terminate.is_set():
                break

            if process.is_alive():
                terminated = True
                _kill_process(process, logger)

            if terminated:
                _set_task_finished(redis, queue, task_id, task_hash_key,
                    RESULT_FAILED,
                    logger=logger,
                    error_reason= "task was pubsub killed" if killed else "task was terminated")

            elif (not hasattr(process, '_popen')
               or not hasattr(process._popen, 'returncode')):
                _set_task_finished(redis, queue, task_id, task_hash_key,
                        RESULT_FAILED,
                        logger=logger,
                        error_reason= 'task was never executed for some reason')

            elif process._popen.returncode != 0:
                _set_task_finished(redis, queue, task_id, task_hash_key,
                    RESULT_FAILED,
                    logger=logger,
                    error_reason= "task's process returncode was {0}".format(process._popen.returncode))

            if _terminate.is_set():
                break

            task_id = None
            task_hash_key = None
            process = None

    except KeyboardInterrupt:
        logger.info('KeyboardInterrupt worker')
        _terminate.set()

    if _terminate.is_set():
        if process is not None:
            _kill_process(process, logger)

        if (task_id is not None and task_hash_key is not None):
            _set_task_finished_with_timeout(queue, task_id, task_hash_key,
                    RESULT_FAILED,
                    error_reason= 'task / process was killed before completion',
                    error_exception=traceback.format_exc(),
                    timeout=6)

    _deregister_worker_with_timeout(worker_uuid, timeout=2)

    cmd_pubsub.close()
Example #5
0
def _exexcute_task(module, queue, task_id, task_hash_key):

    redis = create_redis_connection()
    logger = _create_logger()
    try:
        task = redis.hmget(task_hash_key,
                            (TASK_HKEY_FUNCTION,
                            TASK_HKEY_STATE,
                            TASK_HKEY_ARGS,
                            TASK_HKEY_VIRTUAL_MEMORY_LIMIT))
        print task

        function = task[0]
        state = task[1]
        args = task[2]
        virtual_memory_limit = task[3]

        if function is None or len(function) == 0:
            _set_task_finished(redis, queue, task_id, task_hash_key,
                          RESULT_FAILED,
                          error_reason='for function to execute was not supplied')
            return

        elif state != STATE_PENDING:
            _set_task_finished(redis, queue, task_id, task_hash_key,
                          RESULT_FAILED,
                          error_reason='to execute a task its state must be "{0}" not "{1}"'.format(STATE_PENDING,
                                                                                                    state))
            return

        _set_task_exexcuting(redis, task_hash_key)

        logger.info('executing task_id:{0}\nfunction: {1}\nargs: {2}\n virtual_memory_limit:{3}\n'.format(task_id,
                                                                         function,
                                                                         args,
                                                                         virtual_memory_limit))
        logger.info('--------------------------------------')

        if virtual_memory_limit:
            if isinstance(virtual_memory_limit, basestring):
                virtual_memory_limit = int(virtual_memory_limit)
            if virtual_memory_limit > 0:
                set_virtual_memory_limit(virtual_memory_limit)

        func = getattr(module, function)
        setattr(func, 'task_id', task_id)

        if args:
            result_value = func(**json.loads(args))
        else:
            result_value = func()

        if result_value:
            result_value = json.dumps(result_value, indent=2)

        _set_task_finished(redis,
                           queue,
                           task_id,
                           task_hash_key,
                           RESULT_SUCCESSFUL,
                           result_value,
                           logger=logger)

    except KeyboardInterrupt:
        logger.info('KeyboardInterrupt _exexcute_task')

    except Exception as ex:
        logger.info(traceback.format_exc())
        _set_task_finished(redis, queue, task_id, task_hash_key,
                      RESULT_FAILED,
                      logger=logger,
                      error_reason= '{0}: {1}'.format(type(ex), ex.message),
                      error_exception=traceback.format_exc())