'Run the method associated to a given job
It takes care of logging and exception handling.
:param model_name: model name on which the job method is located.
:param method_name: name of the method to call when this job is processed.
:param args: arguments of the method (without the usual self, cr, uid).
:param job_id: job id.'

@api.model
def _callback(self, model_name, method_name, args, job_id):

    try:
        args = str2tuple(args)
        if (self.pool != self.pool.check_signaling()):
            self.env.reset()
            self = self.env()[self._name]
        if (model_name in self.env):
            model = self.env[model_name]
            if hasattr(model, method_name):
                log_depth = (None if _logger.isEnabledFor(logging.DEBUG) else 1)
                odoo.netsvc.log(_logger, logging.DEBUG, 'cron.object.execute', ((self._cr.dbname, self._uid, '*', model_name, method_name) + tuple(args)), depth=log_depth)
                start_time = False
                if _logger.isEnabledFor(logging.DEBUG):
                    start_time = time.time()
                getattr(model, method_name)(*args)
                if (start_time and _logger.isEnabledFor(logging.DEBUG)):
                    end_time = time.time()
                    _logger.debug('%.3fs    (%s,    %s)', (end_time - start_time), model_name, method_name)
                self.pool.signal_caches_change()
            else:
                _logger.warning("Method    '%s.%s'    does    not    exist.", model_name, method_name)
        else:
            _logger.warning('Model    %r    does    not    exist.', model_name)
    except Exception as e:
        _logger.exception('Call    of    self.env[%r].%s(*%r)    failed    in    Job    #%s', model_name, method_name, args, job_id)
        self._handle_callback_exception(model_name, method_name, args, job_id, e)
