Exemplo n.º 1
0
def _simulation_run_status(data, quiet=False):
    """Look for simulation status and output

    Args:
        data (dict): request
        quiet (bool): don't write errors to log

    Returns:
        dict: status response
    """
    try:
        #TODO(robnagler): Lock
        rep = simulation_db.report_info(data)
        is_processing = runner.job_is_processing(rep.job_id)
        is_running = rep.job_status in _RUN_STATES
        res = {'state': rep.job_status}
        pkdc(
            '{}: is_processing={} is_running={} state={} cached_data={}',
            rep.job_id,
            is_processing,
            is_running,
            rep.job_status,
            bool(rep.cached_data),
        )
        if is_processing and not is_running:
            runner.job_race_condition_reap(rep.job_id)
            pkdc('{}: is_processing and not is_running', rep.job_id)
            is_processing = False
        template = sirepo.template.import_module(data)
        if is_processing:
            if not rep.cached_data:
                return _simulation_error(
                    'input file not found, but job is running',
                    rep.input_file,
                )
        else:
            is_running = False
            if rep.run_dir.exists():
                if hasattr(template,
                           'prepare_output_file') and 'models' in data:
                    template.prepare_output_file(rep.run_dir, data)
                res2, err = simulation_db.read_result(rep.run_dir)
                if err:
                    if simulation_db.is_parallel(data):
                        # allow parallel jobs to use template to parse errors below
                        res['state'] = 'error'
                    else:
                        if hasattr(template, 'parse_error_log'):
                            res = template.parse_error_log(rep.run_dir)
                            if res:
                                return res
                        return _simulation_error(err, 'error in read_result',
                                                 rep.run_dir)
                else:
                    res = res2
        if simulation_db.is_parallel(data):
            new = template.background_percent_complete(
                rep.model_name,
                rep.run_dir,
                is_running,
            )
            new.setdefault('percentComplete', 0.0)
            new.setdefault('frameCount', 0)
            res.update(new)
        res['parametersChanged'] = rep.parameters_changed
        if res['parametersChanged']:
            pkdlog(
                '{}: parametersChanged=True req_hash={} cached_hash={}',
                rep.job_id,
                rep.req_hash,
                rep.cached_hash,
            )
        #TODO(robnagler) verify serial number to see what's newer
        res.setdefault('startTime', _mtime_or_now(rep.input_file))
        res.setdefault('lastUpdateTime', _mtime_or_now(rep.run_dir))
        res.setdefault('elapsedTime', res['lastUpdateTime'] - res['startTime'])
        if is_processing:
            res['nextRequestSeconds'] = simulation_db.poll_seconds(
                rep.cached_data)
            res['nextRequest'] = {
                'report': rep.model_name,
                'reportParametersHash': rep.cached_hash,
                'simulationId': rep.cached_data['simulationId'],
                'simulationType': rep.cached_data['simulationType'],
            }
        pkdc(
            '{}: processing={} state={} cache_hit={} cached_hash={} data_hash={}',
            rep.job_id,
            is_processing,
            res['state'],
            rep.cache_hit,
            rep.cached_hash,
            rep.req_hash,
        )
    except Exception:
        return _simulation_error(pkdexc(), quiet=quiet)
    return res
Exemplo n.º 2
0
def _simulation_run_status(req, quiet=False):
    """Look for simulation status and output

    Args:
        req (dict): parsed simulation data
        quiet (bool): don't write errors to log

    Returns:
        dict: status response
    """
    reqd = _reqd(req)
    in_run_simulation = 'models' in req.req_data
    if in_run_simulation:
        req.req_data.models.computeJobCacheKey = PKDict(
            computeJobHash=reqd.req_hash, )
    is_processing = runner.job_is_processing(reqd.jid)
    is_running = reqd.job_status in _RUN_STATES
    res = PKDict(state=reqd.job_status)
    pkdc(
        '{}: is_processing={} is_running={} state={} cached_data={}',
        reqd.jid,
        is_processing,
        is_running,
        reqd.job_status,
        bool(reqd.cached_data),
    )
    if is_processing and not is_running:
        runner.job_race_condition_reap(reqd.jid)
        pkdc('{}: is_processing and not is_running', reqd.jid)
        is_processing = False
    template = sirepo.template.import_module(req.type)
    if is_processing:
        if not reqd.cached_data:
            return _subprocess_error(
                error='input file not found, but job is running',
                input_file=reqd.input_file,
            )
    else:
        is_running = False
        if reqd.run_dir.exists():
            res = simulation_db.read_result(reqd.run_dir)
            if res.state == sirepo.job.ERROR:
                return _subprocess_error(
                    error='read_result error: ' +
                    res.get('error', '<no error in read_result>'),
                    run_dir=reqd.run_dir,
                )
            if (in_run_simulation and res.state == sirepo.job.COMPLETED
                    and hasattr(template, 'prepare_output_file')):
                template.prepare_output_file(reqd.run_dir, req.req_data)
                res = simulation_db.read_result(reqd.run_dir)
    if reqd.is_parallel:
        new = template.background_percent_complete(
            reqd.model_name,
            reqd.run_dir,
            is_running,
        )
        new.setdefault('percentComplete', 0.0)
        new.setdefault('frameCount', 0)
        res.update(new)
    res['parametersChanged'] = reqd.parameters_changed
    if res['parametersChanged']:
        pkdlog(
            '{}: parametersChanged=True req_hash={} cached_hash={}',
            reqd.jid,
            reqd.req_hash,
            reqd.cached_hash,
        )
    if reqd.is_parallel and reqd.cached_data:
        s = reqd.cached_data.models.computeJobCacheKey
        t = s.get('computeJobSerial', 0)
        res.pksetdefault(
            computeJobHash=s.computeJobHash,
            computeJobSerial=t,
            elapsedTime=lambda: int(
                (res.get('lastUpdateTime') or _mtime_or_now(reqd.run_dir)) - t
                if t else 0, ),
        )
    if is_processing:
        res.nextRequestSeconds = reqd.sim_data.poll_seconds(reqd.cached_data)
        res.nextRequest = PKDict(
            report=reqd.model_name,
            simulationId=reqd.cached_data.simulationId,
            simulationType=reqd.cached_data.simulationType,
            **reqd.cached_data.models.computeJobCacheKey)
    pkdc(
        '{}: processing={} state={} cache_hit={} cached_hash={} data_hash={}',
        reqd.jid,
        is_processing,
        res['state'],
        reqd.cache_hit,
        reqd.cached_hash,
        reqd.req_hash,
    )
    return res