Beispiel #1
0
def show_task_log():
    "Show log of tasks run."

    run_db = ox_run_db.create()
    start_utc = request.args.get('start_utc', None)
    end_utc = request.args.get('end_utc', None)
    limit = int(request.args.get('limit', 100))
    tasks = run_db.get_tasks(start_utc=start_utc, end_utc=end_utc)
    tasks = run_db.limit_task_count(tasks, limit)
    other = []
    task_dict = collections.OrderedDict([('started', []), ('finished', [])])
    for item in reversed(
            sorted(tasks, key=lambda t: (t.task_end_utc, t.task_start_utc))):
        if item.task_status in task_dict:
            task_dict[item.task_status].append(item)
        else:
            other.append(item)
    task_dict['other'] = other

    return render_template('task_log.html',
                           title='Task log',
                           start_utc=start_utc,
                           end_utc=end_utc,
                           task_dict=task_dict,
                           limit=limit)
Beispiel #2
0
def check_jobs():
    """Check if various jobs have been running.

The following URL parameters can be provided:
  - names:
    - Comma separated list of names of tasks to check.
  - seconds (default 3600)
    - How many seconds are allowed since last completion of a job
      named in the names parameter.

If a job in names has not finished within the given seconds,
then we complain.
    """
    my_db = ox_run_db.create()
    late_jobs = []
    try:  # Use try block so return 500 if see an exception
        if not _check_health_token():
            abort(403)
        seconds = int(request.args.get('seconds', '3600'))
        name_list = request.args.get('names').split(',')
        my_now = datetime.datetime.utcnow()
        for name in name_list:
            logging.info('Checking task "%s"', name)
            latest = my_db.get_latest(name)
            if not latest:
                late_jobs.append((name, 'not found', 'N/A'))
            else:
                task_end_utc = datetime.datetime.strptime(
                    str(latest.task_end_utc), '%Y-%m-%d %H:%M:%S.%f')
                gap = (my_now - task_end_utc).total_seconds()
                if gap > seconds:
                    late_jobs.append((name, task_end_utc, gap))
        if late_jobs:
            msg = '\n'.join(['Found late jobs:'] + [
                '%s: finished at %s which is %s > %s seconds late' %
                (name, task_end_utc, gap, seconds)
                for (name, task_end_utc, gap) in late_jobs
            ])
            logging.error(msg)
            return json.dumps({
                'result': 'error',
                'error': msg
            }), 412, {
                'ContentType': 'application/json'
            }
    except Exception as problem:  # pylint: disable=broad-except
        logging.error('Problem in health_check: %s', str(problem))
        abort(500)
    return json.dumps({'result': 'success'}), 200, {
        'ContentType': 'application/json'
    }
Beispiel #3
0
def list_tasks():
    "Show list of tasks so you can inspect them."

    my_db = ox_run_db.create()
    limit = int(request.args.get('limit', 100))
    start_utc = request.args.get('start_utc', None)
    end_utc = request.args.get('end_utc', None)
    tasks = my_db.get_tasks(start_utc=start_utc, end_utc=end_utc)
    total = len(tasks)
    tasks = my_db.limit_task_count(tasks, limit)
    return render_template('task_list.html',
                           title='Task List',
                           tasks=tasks,
                           total=total,
                           limit=limit)
Beispiel #4
0
def delete_task_from_db():
    """Delete a task from the task database.

    This is mainly intended to be used from the task list and not so
    useful directly since it requires the task_id.
    """
    task_id = request.args.get('task_id', None)
    if task_id:
        run_db = ox_run_db.create()
        run_db.delete_task(task_id)
        return render_template(
            'generic_display.html',
            commentary=('Delete task with id %s from database.' % task_id))
    return render_template(
        'generic_display.html',
        commentary=('Found no task_id so cannot do anything.'))
Beispiel #5
0
    def run_ox_task(cls, ox_herd_task):
        """Entry point to run the task.

        This is what python rq or other managers will use to start the task.
        """
        job_name = ox_herd_task.name
        run_db = ox_herd_task.run_db
        rdb = ox_run_db.create(run_db)
        cls.pre_call(ox_herd_task, rdb)
        try:
            result = cls.main_call(ox_herd_task)
        except Exception as problem:
            logging.error('For job %s; storing exception result: %s',
                          job_name, str(problem))
            cls.post_call(ox_herd_task, rdb, str(problem), 'exception')
            raise
        cls.post_call(ox_herd_task, rdb, result)

        return result
Beispiel #6
0
def show_task():
    "Show information about a task."

    task_id = request.args.get('task_id', None)
    run_db = ox_run_db.create()
    try:
        task_data = run_db.get_task(task_id)
        if not task_data:
            raise KeyError('No task with id %s' % str(task_id))
    except Exception as problem:  # pylint: disable=broad-except
        return render_template(
            'generic_error.html',
            title='Could not find task',
            commentary='Could not find task with id %s because %s' %
            (task_id, problem))

    template = request.args.get('template', task_data.template)
    template = template if (template and template.strip()
                            and template != 'default') else (
                                'generic_ox_task_result.html')
    return render_template(template, title='Task Report', task_data=task_data)
Beispiel #7
0
def record_finished_job():
    """REST API endpoint to record that a job finished.

You can send a request with the following:

  - task_id:
    - The id returned by record_started_job if you have called that.
      If you have not called record_started_job and want to record
      both start and finish in one go then omit this and provide
      task_name instead (see below).
  - task_name:
    - If you have not already called record_started_job and just
      want to record the start and finish of the job, then provide
      a string name in task_name and omit task_id.
  - return_value:
    - Return value of running the task.
    """
    if current_user is None and not _check_health_token():
        abort(403)
    my_db = ox_run_db.create()
    try:
        record = json.loads(request.data)
        task_id = record.get('task_id', None)
        if task_id is None:
            task_id = my_db.record_task_start(record['task_name'])
            record.pop('task_name')
            record['task_id'] = task_id
        my_db.record_task_finish(**record)
    except KeyError as problem:
        return json.dumps({
            'result':
            'error',
            'error':
            'Could not find required value for "%s"' % str(problem)
        }), 400, {
            'ContentType': 'application/json'
        }
    return json.dumps({'result': 'success'}), 200, {
        'ContentType': 'application/json'
    }
Beispiel #8
0
def get_latest(task_name):
    """Get info on latest finished version of task named <task_name>

If successful, you can do something like the folllowing to get
the completion time of the latest task:

   datetime.datetime.strptime(my_request.json()['task_end_utc'],
      '%Y-%m-%d %H:%M:%S.%f')

    """
    task_result = ox_run_db.create().get_latest(task_name)
    if task_result is None:
        result = {}
    else:
        result = {
            n: getattr(task_result, n, None)
            for n in [
                'task_id', 'task_name', 'task_start_utc', 'task_end_utc',
                'return_value', 'json_data', 'pickle_data'
            ]
        }
    return json.dumps(result), 200, {'ContentType': 'application/json'}