예제 #1
0
파일: base.py 프로젝트: tengqm/senlin
def ActionProc(context, action_id, worker_id):
    '''Action process.'''

    # Step 1: lock the action for execution
    timestamp = wallclock()
    result = db_api.action_acquire(context, action_id, worker_id, timestamp)
    if result is None:
        LOG.debug(_('Failed locking action "%s" for execution'), action_id)
        return False

    # Step 2: materialize the action object
    action = Action.load(context, action_id=action_id)

    LOG.info(_LI('Action %(name)s [%(id)s] started'),
             {'name': six.text_type(action.action), 'id': action.id})

    reason = 'Action completed'
    try:
        # Step 3: execute the action
        result, reason = action.execute()

        # NOTE: The following exception report is not giving useful
        # information for some reasons.
        # except Exception as ex:
        # We catch exception here to make sure the following logics are
        # executed.
        # result = action.RES_ERROR
        # reason = six.text_type(ex)
        # LOG.error(_('Exception occurred in action execution[%(action)s]: '
        #            '%(reason)s'), {'action': action.action,
        #                            'reason': reason})
    finally:
        # NOTE: locks on action is eventually released here by status update
        action.set_status(result, reason)
예제 #2
0
    def start_action(self, worker_id, action_id=None):
        '''Run the given action in a sub-thread.

        Release the action lock when the thread finishes?

        :param workder_id: ID of the worker thread; we fake workers using
                           senlin engines at the moment.
        :param action_id: ID of the action to be executed. None means the
                          1st ready action will be scheduled to run.
        '''
        def release(thread, action_id):
            '''Callback function that will be passed to GreenThread.link().'''
            # Remove action thread from thread list
            self.workers.pop(action_id)

        timestamp = wallclock()
        if action_id is not None:
            action = db_api.action_acquire(self.db_session, action_id,
                                           worker_id, timestamp)
        else:
            action = db_api.action_acquire_1st_ready(self.db_session,
                                                     worker_id,
                                                     timestamp)
        if not action:
            return

        th = self.start(action_mod.ActionProc, self.db_session, action.id)
        self.workers[action.id] = th
        th.link(release, action.id)
        return th
예제 #3
0
    def start_action(self, worker_id, action_id=None):
        '''Run action(s) in sub-thread(s).

        :param worker_id: ID of the worker thread; we fake workers using
                          senlin engines at the moment.
        :param action_id: ID of the action to be executed. None means all
                          ready actions will be acquired and scheduled to run.
        '''
        def launch(action_id):
            '''Launch a sub-thread to run given action.'''
            th = self.start(action_mod.ActionProc, self.db_session, action_id)
            self.workers[action_id] = th
            th.link(release, action_id)
            return th

        def release(thread, action_id):
            '''Callback function that will be passed to GreenThread.link().'''
            # Remove action thread from thread list
            self.workers.pop(action_id)

        actions_launched = 0
        if action_id is not None:
            timestamp = wallclock()
            action = db_api.action_acquire(self.db_session, action_id,
                                           worker_id, timestamp)
            if action:
                launch(action.id)
                actions_launched += 1

        batch_size = cfg.CONF.max_actions_per_batch
        batch_interval = cfg.CONF.batch_interval
        while True:
            timestamp = wallclock()
            action = db_api.action_acquire_1st_ready(self.db_session,
                                                     worker_id, timestamp)
            if action:
                if batch_size > 0 and 'NODE' in action.action:
                    if actions_launched < batch_size:
                        launch(action.id)
                        actions_launched += 1
                    else:
                        msg = _('Engine %(id)s has launched %(num)s node '
                                'actions consecutively, stop scheduling '
                                'node action for %(interval)s second...') % {
                                    'id': worker_id,
                                    'num': batch_size,
                                    'interval': batch_interval
                                }
                        LOG.debug(msg)
                        sleep(batch_interval)
                        launch(action.id)
                        actions_launched = 1
                else:
                    launch(action.id)
            else:
                break
예제 #4
0
파일: base.py 프로젝트: KongJustin/senlin
def ActionProc(context, action_id, worker_id):
    '''Action process.'''

    # Step 1: materialize the action object
    action = Action.load(context, action_id=action_id)
    if action is None:
        LOG.error(_LE('Action "%s" could not be found.'), action_id)
        return False

    # Step 2: lock the action for execution
    timestamp = wallclock()
    res = db_api.action_acquire(action.context, action_id, worker_id,
                                timestamp)
    if res is None:
        LOG.warning(_LE('Failed in locking action "%s".'), action_id)
        return False

    action.owner = res.owner
    action.start_time = res.start_time
    # TODO(Anyone): Remove context usage in event module
    EVENT.info(action.context, action, action.action, 'START')

    reason = 'Action completed'
    success = True
    try:
        # Step 3: execute the action
        result, reason = action.execute()
    except Exception as ex:
        # We catch exception here to make sure the following logics are
        # executed.
        result = action.RES_ERROR
        reason = six.text_type(ex)
        LOG.exception(_('Unexpected exception occurred during action '
                        '%(action)s (%(id)s) execution: %(reason)s'),
                      {'action': action.action, 'id': action.id,
                       'reason': reason})
        success = False
    finally:
        # NOTE: locks on action is eventually released here by status update
        action.set_status(result, reason)

    return success
예제 #5
0
파일: scheduler.py 프로젝트: onesafe/senlin
    def start_action(self, worker_id, action_id=None):
        '''Run action(s) in sub-thread(s).

        :param worker_id: ID of the worker thread; we fake workers using
                          senlin engines at the moment.
        :param action_id: ID of the action to be executed. None means all
                          ready actions will be acquired and scheduled to run.
        '''
        def launch(action_id):
            '''Launch a sub-thread to run given action.'''
            th = self.start(action_mod.ActionProc, self.db_session, action_id)
            self.workers[action_id] = th
            th.link(release, action_id)
            return th

        def release(thread, action_id):
            '''Callback function that will be passed to GreenThread.link().'''
            # Remove action thread from thread list
            self.workers.pop(action_id)

        if action_id is not None:
            timestamp = wallclock()
            action = db_api.action_acquire(self.db_session, action_id,
                                           worker_id, timestamp)
            if action:
                launch(action.id)

        while True:
            timestamp = wallclock()
            action = db_api.action_acquire_1st_ready(self.db_session,
                                                     worker_id,
                                                     timestamp)
            # TODO(Yanyan Hu): Enable batch control.
            if action:
                launch(action.id)
            else:
                break
예제 #6
0
 def acquire(cls, context, action_id, owner, timestamp):
     return db_api.action_acquire(context, action_id, owner, timestamp)
예제 #7
0
파일: action.py 프로젝트: jonnary/senlin
 def acquire(cls, context, action_id, owner, timestamp):
     return db_api.action_acquire(context, action_id, owner, timestamp)