diff --git a/awx/ui/client/features/output/index.controller.js b/awx/ui/client/features/output/index.controller.js index b65cb52a68..f2b6235476 100644 --- a/awx/ui/client/features/output/index.controller.js +++ b/awx/ui/client/features/output/index.controller.js @@ -114,7 +114,12 @@ function next () { } return shift() - .then(() => append(events)); + .then(() => append(events)) + .then(() => { + if(scroll.isMissing()) { + return next(); + } + }); }); } @@ -193,6 +198,11 @@ function scrollHome () { .then(() => { scroll.resetScrollPosition(); scroll.resume(); + }) + .then(() => { + if(scroll.isMissing()) { + return next(); + } }); }); } diff --git a/awx/ui/client/features/output/index.js b/awx/ui/client/features/output/index.js index ebf69f5243..b56e09a1ff 100644 --- a/awx/ui/client/features/output/index.js +++ b/awx/ui/client/features/output/index.js @@ -13,8 +13,8 @@ const Template = require('~features/output/index.view.html'); const MODULE_NAME = 'at.features.output'; const PAGE_CACHE = true; -const PAGE_LIMIT = 3; -const PAGE_SIZE = 100; +const PAGE_LIMIT = 5; +const PAGE_SIZE = 50; const WS_PREFIX = 'ws'; function resolveResource ( diff --git a/awx/ui/client/features/output/scroll.service.js b/awx/ui/client/features/output/scroll.service.js index ae186798e4..a568813ddc 100644 --- a/awx/ui/client/features/output/scroll.service.js +++ b/awx/ui/client/features/output/scroll.service.js @@ -1,4 +1,5 @@ const ELEMENT_CONTAINER = '.at-Stdout-container'; +const ELEMENT_TBODY = '#atStdoutResultTable'; const DELAY = 100; const THRESHOLD = 0.1; @@ -158,6 +159,7 @@ function JobScrollService ($q, $timeout) { }; this.isLocked = () => this.state.locked; + this.isMissing = () => $(ELEMENT_TBODY)[0].clientHeight < this.getViewableHeight(); } JobScrollService.$inject = ['$q', '$timeout']; diff --git a/awx/ui/client/features/output/stream.service.js b/awx/ui/client/features/output/stream.service.js index a7e73cbdfa..65aa44ea43 100644 --- a/awx/ui/client/features/output/stream.service.js +++ b/awx/ui/client/features/output/stream.service.js @@ -27,6 +27,14 @@ function JobStreamService ($q) { listen }; + this.lines = { + used: [], + missing: [], + ready: false, + min: 0, + max: 0 + }; + this.hooks.listen(resource.ws.namespace, this.listen); }; @@ -72,6 +80,31 @@ function JobStreamService ($q) { } }; + this.checkLines = data => { + for (let i = data.start_line; i < data.end_line; i++) { + if (i > this.lines.max) { + this.lines.max = i; + } + + this.lines.used.push(i); + } + + let missing = []; + for (let i = this.lines.min; i < this.lines.max; i++) { + if (this.lines.used.indexOf(i) === -1) { + missing.push(i); + } + } + + if (missing.length === 0) { + this.lines.ready = true; + this.lines.min = this.lines.max + 1; + this.lines.used = []; + } else { + this.lines.ready = false; + } + }; + this.listen = data => { this.lag++; @@ -87,10 +120,11 @@ function JobStreamService ($q) { } } + this.checkLines(data); this.buffer(data); this.count++; - if (this.isPaused() || !this.isBatchFull()) { + if (!this.isReadyToRender()) { return $q.resolve(); } @@ -166,6 +200,9 @@ function JobStreamService ($q) { this.state.ending = true; }; + this.isReadyToRender = () => this.isEnding() || + (!this.isPaused() && this.hasAllLines() && this.isBatchFull()); + this.hasAllLines = () => this.lines.ready; this.isBatchFull = () => this.count % this.framesPerRender === 0; this.isPaused = () => this.state.paused; this.isPausing = () => this.state.pausing;