Commit 5f7690f3 authored by Yakubov, Sergey's avatar Yakubov, Sergey
Browse files

Merge branch 'gzi-job-monitoring' into 'dev'

Load stdout when requesting job status

See merge request !42
parents dd9ccb72 74e867e0
Loading
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
<template>
    <div>
        <job-details-provider auto-refresh :jobId="job_id" @update:result="updateJob" />
        <job-details-provider auto-refresh :jobId="job_id" :stdout_start=stdout_position :stdout_char_count=stdout_char_count @update:result="updateJob" />
        <h3>Job Information</h3>
        <table id="job-information" class="tabletip info_data_table">
            <tbody>
@@ -37,7 +37,7 @@
                    </td>
                </tr>
                <code-row v-if="job" id="command-line" :code-label="'Command Line'" :code-item="job.command_line" />
                <code-row v-if="job" id="stdout" :code-label="'Tool Standard Output'" :code-item="job.tool_stdout" />
                <code-row v-if="job" id="stdout" :code-label="'Tool Standard Output'" :code-item="stdout_text" />
                <code-row v-if="job" id="stderr" :code-label="'Tool Standard Error'" :code-item="job.tool_stderr" />
                <code-row
                    v-if="job && job.traceback"
@@ -103,6 +103,9 @@ export default {
    data() {
        return {
            job: null,
            stdout_position: 0,
            stdout_char_count: 50000,
            stdout_text: "",
        };
    },
    computed: {
@@ -115,12 +118,30 @@ export default {
            return this.job && !JOB_STATES_MODEL.NON_TERMINAL_STATES.includes(this.job.state);
        },
    },
    updated() {
        try {
            const stdout_block = document.querySelector("#stdout").querySelector(".code");
            // if user is scrolled above the bottom of the code element, then no need to update the stdout
            if (stdout_block.scrollTop <= stdout_block.scrollHeight - 3000) {
                this.stdout_char_count = 0;
            } else {
                this.stdout_char_count = 50000;
            }
        } catch(exception) {
            console.log(exception);
        }
    },
    methods: {
        getAppRoot() {
            return getAppRoot();
        },
        updateJob(job) {
            this.job = job;
            // Keep stdout in memory and only fetch new text via JobProvider
            if (job.tool_stdout != null) {
                this.stdout_text += job.tool_stdout;
                this.stdout_position += job.tool_stdout.length;
            }
        },
    },
};
+2 −2
Original line number Diff line number Diff line
@@ -5,8 +5,8 @@ import { rethrowSimple } from "utils/simple-error";
import { stateIsTerminal } from "./utils";
import { cleanPaginationParameters } from "./utils";

async function jobDetails({ jobId }) {
    const url = `${getAppRoot()}api/jobs/${jobId}?full=True`;
async function jobDetails({ jobId, stdout_start = 0, stdout_char_count = 0 }) {
    const url = `${getAppRoot()}api/jobs/${jobId}?full=True&stdout_start_pos=${stdout_start}&stdout_count=${stdout_char_count}`;
    try {
        const { data } = await axios.get(url);
        return data;
+5 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import logging
import os
import re
import subprocess
from pathlib import Path
from time import sleep

import packaging.version
@@ -644,6 +645,10 @@ class PulsarJobRunner(AsynchronousJobRunner):
            run_results = client.full_status()
            remote_metadata_directory = run_results.get("metadata_directory", None)
            stdout = run_results.get("stdout", "")
            if stdout == "":
                stdout_path = Path(job_wrapper.working_directory) / "outputs" / "tool_stdout"
                stdout_file = open(stdout_path, "r")
                stdout = stdout_file.read()
            stderr = run_results.get("stderr", "")
            exit_code = run_results.get("returncode", None)
            pulsar_outputs = PulsarOutputs.from_status_response(run_results)
+15 −2
Original line number Diff line number Diff line
import json
import logging
import typing
from pathlib import Path
from datetime import (
    date,
    datetime,
@@ -56,7 +57,7 @@ from galaxy.util.search import (
    parse_filters_structured,
    RawTextTerm,
)

import traceback
log = logging.getLogger(__name__)


@@ -219,7 +220,7 @@ class JobManager:
        )
        return self.job_lock()

    def get_accessible_job(self, trans, decoded_job_id):
    def get_accessible_job(self, trans, decoded_job_id, stdout_start_pos=-1, stdout_count=0):
        job = trans.sa_session.query(trans.app.model.Job).filter(trans.app.model.Job.id == decoded_job_id).first()
        if job is None:
            raise ObjectNotFound()
@@ -236,6 +237,18 @@ class JobManager:
                if not self.dataset_manager.is_accessible(data_assoc.dataset.dataset, trans.user):
                    raise ItemAccessibilityException("You are not allowed to rerun this job.")
        trans.sa_session.refresh(job)

        # If stdout_count and stdout_start_pos are good values, then load standard out and add it to status
        if job.state == job.states.RUNNING and stdout_count > 0 and stdout_start_pos > -1:
            try:
                working_directory = trans.app.object_store.get_filename(job, base_dir="job_work", dir_only=True, obj_dir=True)
                stdout_path = Path(working_directory) / "outputs" / "tool_stdout"
                stdout_file = open(stdout_path, "r")
                stdout_file.seek(stdout_start_pos)
                job.job_stdout = stdout_file.read(stdout_count)
                job.tool_stdout = job.job_stdout
            except Exception as e:
                log.error("Could not read STDOUT: %s", e)
        return job

    def stop(self, job, message=None):
+5 −1
Original line number Diff line number Diff line
@@ -104,6 +104,10 @@ class JobFilesAPIController(BaseGalaxyAPIController):
        target_dir = os.path.dirname(path)
        util.safe_makedirs(target_dir)
        try:
            if os.path.exists(path):
                with open(path, 'ab') as dest:
                    shutil.copyfileobj(open(input_file.name, 'rb'), dest)
            else:
                shutil.move(input_file.name, path)
        finally:
            try:
Loading