Loading client/src/components/JobInformation/JobInformation.vue +14 −25 Original line number Diff line number Diff line <template> <div> <job-details-provider auto-refresh :jobId="job_id" :page_start=stdout_start :page_end=stdout_end @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> Loading Loading @@ -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" Loading Loading @@ -103,11 +103,9 @@ export default { data() { return { job: null, stdout_start: 1, stdout_end: 3, stdout_page_length: 5000, stdout_live: true, stdout_old: false, stdout_position: 0, stdout_char_count: 50000, stdout_text: "", }; }, computed: { Loading @@ -123,18 +121,14 @@ export default { updated() { try { const stdout_block = document.querySelector("#stdout").querySelector(".code"); if (stdout_block.scrollTop <= .25 * stdout_block.scrollHeight) { this.stdout_live = false; this.stdout_old = true; } else if (stdout_block.scrollTop >= .75 * stdout_block.scrollHeight) { this.stdout_live = true; this.stdout_old = false; // 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_live = false; this.stdout_old = false; this.stdout_char_count = 50000; } } catch(exception) { console.log("Can not find code div."); console.log(exception); } }, methods: { Loading @@ -143,16 +137,11 @@ export default { }, updateJob(job) { this.job = job; if (this.job.tool_stdout.length >= this.stdout_page_length * 3 && this.stdout_live) { this.stdout_start += 1; this.stdout_end += 1; // 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; } if (!this.stdout_live && this.stdout_old) { this.stdout_start = this.stdout_start > 1 ? this.stdout_start - 1: 1; this.stdout_end = this.stdout_end > 3 ? this.stdout_end - 1: 3; } }, }, }; Loading client/src/components/providers/JobProvider.js +2 −2 Original line number Diff line number Diff line Loading @@ -5,8 +5,8 @@ import { rethrowSimple } from "utils/simple-error"; import { stateIsTerminal } from "./utils"; import { cleanPaginationParameters } from "./utils"; async function jobDetails({ jobId, page_start = 0, page_end = 0 }) { const url = `${getAppRoot()}api/jobs/${jobId}?full=True&stdout_start=${page_start}&stdout_end=${page_end}`; 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; Loading lib/galaxy/managers/jobs.py +6 −8 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ from galaxy.util.search import ( import traceback log = logging.getLogger(__name__) STDOUT_PAGE_SIZE_CHARS = 5000 class JobLock(BaseModel): active: bool = Field(title="Job lock status", description="If active, jobs will not dispatch") Loading Loading @@ -221,7 +220,7 @@ class JobManager: ) return self.job_lock() def get_accessible_job(self, trans, decoded_job_id, stdout_start=0, stdout_end=0): 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() Loading @@ -239,18 +238,17 @@ class JobManager: raise ItemAccessibilityException("You are not allowed to rerun this job.") trans.sa_session.refresh(job) if job.state == job.states.RUNNING and stdout_start > 0: # 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: stdout_path = Path(".").parent.parent.parent.parent.parent / "database/jobs_directory/000" / str( job.id) / "outputs/tool_stdout" stdout_file = open(stdout_path, "r") number_of_pages = stdout_end - stdout_start + 1 if stdout_end > 0 else 1 stdout_file.seek((stdout_start - 1) * STDOUT_PAGE_SIZE_CHARS) job.job_stdout = stdout_file.read(STDOUT_PAGE_SIZE_CHARS * number_of_pages) 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) log.error(traceback.format_exc()) return job def stop(self, job, message=None): Loading lib/galaxy/webapps/galaxy/api/jobs.py +5 −3 Original line number Diff line number Diff line Loading @@ -178,8 +178,8 @@ class FastAPIJobs: id: EncodedDatabaseIdField, trans: ProvidesUserContext = DependsOnTrans, full: Optional[bool] = False, stdout_start: Optional[int] = None, stdout_end: Optional[int] = None, stdout_start_pos: Optional[int] = None, stdout_count: Optional[int] = None, ) -> Dict[str, Any]: """ Return dictionary containing description of job data Loading @@ -187,8 +187,10 @@ class FastAPIJobs: Parameters - id: ID of job to return - full: Return extra information ? - stdout_start_pos: The index of the character to begine reading stdout from - stdout_count: How many characters of stdout to read """ return self.service.show(trans, id, bool(full), int(stdout_start) if stdout_start else 0, int(stdout_end) if stdout_end else 0) return self.service.show(trans, id, bool(full), int(stdout_start_pos) if stdout_start_pos else 0, int(stdout_count) if stdout_count else 0) @router.get("/api/jobs") def index( Loading lib/galaxy/webapps/galaxy/services/jobs.py +3 −3 Original line number Diff line number Diff line Loading @@ -48,11 +48,11 @@ class JobsService: trans: ProvidesUserContext, id: EncodedDatabaseIdField, full: bool = False, stdout_start: int = 0, stdout_end: int = 0, stdout_start_pos: int = 0, stdout_count: int = 0, ) -> Dict[str, Any]: id = trans.app.security.decode_id(id) job = self.job_manager.get_accessible_job(trans, id, stdout_start, stdout_end) job = self.job_manager.get_accessible_job(trans, id, stdout_start_pos, stdout_count) return view_show_job(trans, job, bool(full)) def index( Loading Loading
client/src/components/JobInformation/JobInformation.vue +14 −25 Original line number Diff line number Diff line <template> <div> <job-details-provider auto-refresh :jobId="job_id" :page_start=stdout_start :page_end=stdout_end @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> Loading Loading @@ -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" Loading Loading @@ -103,11 +103,9 @@ export default { data() { return { job: null, stdout_start: 1, stdout_end: 3, stdout_page_length: 5000, stdout_live: true, stdout_old: false, stdout_position: 0, stdout_char_count: 50000, stdout_text: "", }; }, computed: { Loading @@ -123,18 +121,14 @@ export default { updated() { try { const stdout_block = document.querySelector("#stdout").querySelector(".code"); if (stdout_block.scrollTop <= .25 * stdout_block.scrollHeight) { this.stdout_live = false; this.stdout_old = true; } else if (stdout_block.scrollTop >= .75 * stdout_block.scrollHeight) { this.stdout_live = true; this.stdout_old = false; // 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_live = false; this.stdout_old = false; this.stdout_char_count = 50000; } } catch(exception) { console.log("Can not find code div."); console.log(exception); } }, methods: { Loading @@ -143,16 +137,11 @@ export default { }, updateJob(job) { this.job = job; if (this.job.tool_stdout.length >= this.stdout_page_length * 3 && this.stdout_live) { this.stdout_start += 1; this.stdout_end += 1; // 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; } if (!this.stdout_live && this.stdout_old) { this.stdout_start = this.stdout_start > 1 ? this.stdout_start - 1: 1; this.stdout_end = this.stdout_end > 3 ? this.stdout_end - 1: 3; } }, }, }; Loading
client/src/components/providers/JobProvider.js +2 −2 Original line number Diff line number Diff line Loading @@ -5,8 +5,8 @@ import { rethrowSimple } from "utils/simple-error"; import { stateIsTerminal } from "./utils"; import { cleanPaginationParameters } from "./utils"; async function jobDetails({ jobId, page_start = 0, page_end = 0 }) { const url = `${getAppRoot()}api/jobs/${jobId}?full=True&stdout_start=${page_start}&stdout_end=${page_end}`; 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; Loading
lib/galaxy/managers/jobs.py +6 −8 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ from galaxy.util.search import ( import traceback log = logging.getLogger(__name__) STDOUT_PAGE_SIZE_CHARS = 5000 class JobLock(BaseModel): active: bool = Field(title="Job lock status", description="If active, jobs will not dispatch") Loading Loading @@ -221,7 +220,7 @@ class JobManager: ) return self.job_lock() def get_accessible_job(self, trans, decoded_job_id, stdout_start=0, stdout_end=0): 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() Loading @@ -239,18 +238,17 @@ class JobManager: raise ItemAccessibilityException("You are not allowed to rerun this job.") trans.sa_session.refresh(job) if job.state == job.states.RUNNING and stdout_start > 0: # 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: stdout_path = Path(".").parent.parent.parent.parent.parent / "database/jobs_directory/000" / str( job.id) / "outputs/tool_stdout" stdout_file = open(stdout_path, "r") number_of_pages = stdout_end - stdout_start + 1 if stdout_end > 0 else 1 stdout_file.seek((stdout_start - 1) * STDOUT_PAGE_SIZE_CHARS) job.job_stdout = stdout_file.read(STDOUT_PAGE_SIZE_CHARS * number_of_pages) 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) log.error(traceback.format_exc()) return job def stop(self, job, message=None): Loading
lib/galaxy/webapps/galaxy/api/jobs.py +5 −3 Original line number Diff line number Diff line Loading @@ -178,8 +178,8 @@ class FastAPIJobs: id: EncodedDatabaseIdField, trans: ProvidesUserContext = DependsOnTrans, full: Optional[bool] = False, stdout_start: Optional[int] = None, stdout_end: Optional[int] = None, stdout_start_pos: Optional[int] = None, stdout_count: Optional[int] = None, ) -> Dict[str, Any]: """ Return dictionary containing description of job data Loading @@ -187,8 +187,10 @@ class FastAPIJobs: Parameters - id: ID of job to return - full: Return extra information ? - stdout_start_pos: The index of the character to begine reading stdout from - stdout_count: How many characters of stdout to read """ return self.service.show(trans, id, bool(full), int(stdout_start) if stdout_start else 0, int(stdout_end) if stdout_end else 0) return self.service.show(trans, id, bool(full), int(stdout_start_pos) if stdout_start_pos else 0, int(stdout_count) if stdout_count else 0) @router.get("/api/jobs") def index( Loading
lib/galaxy/webapps/galaxy/services/jobs.py +3 −3 Original line number Diff line number Diff line Loading @@ -48,11 +48,11 @@ class JobsService: trans: ProvidesUserContext, id: EncodedDatabaseIdField, full: bool = False, stdout_start: int = 0, stdout_end: int = 0, stdout_start_pos: int = 0, stdout_count: int = 0, ) -> Dict[str, Any]: id = trans.app.security.decode_id(id) job = self.job_manager.get_accessible_job(trans, id, stdout_start, stdout_end) job = self.job_manager.get_accessible_job(trans, id, stdout_start_pos, stdout_count) return view_show_job(trans, job, bool(full)) def index( Loading