From 1c414789fb26a86bfbeca3094093e263a3d67236 Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Tue, 5 Jun 2018 09:33:35 -0400 Subject: [PATCH] fix memory leak in output render service --- .../features/output/index.controller.js | 20 ++---- .../client/features/output/render.service.js | 65 ++++++++++++------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/awx/ui/client/features/output/index.controller.js b/awx/ui/client/features/output/index.controller.js index 6c50a10abc..d2daef915e 100644 --- a/awx/ui/client/features/output/index.controller.js +++ b/awx/ui/client/features/output/index.controller.js @@ -2,6 +2,7 @@ let $compile; let $filter; let $q; let $scope; +let $state; let page; let render; @@ -19,6 +20,7 @@ function JobsIndexController ( _$filter_, _$q_, _$scope_, + _$state_, _resource_, _page_, _scroll_, @@ -33,6 +35,7 @@ function JobsIndexController ( $filter = _$filter_; $q = _$q_; $scope = _$scope_; + $state = _$state_; resource = _resource_; page = _page_; @@ -352,19 +355,9 @@ function devClear () { render.clear().then(() => init()); } -// function showHostDetails (id) { -// jobEvent.request('get', id) -// .then(() => { -// const title = jobEvent.get('host_name'); - -// vm.host = { -// menu: true, -// stdout: jobEvent.get('stdout') -// }; - -// $scope.jobs.modal.show(title); -// }); -// } +function showHostDetails (id, uuid) { + $state.go('output.host-event.json', { eventId: id, taskUuid: uuid }); +} // function toggle (uuid, menu) { // const lines = $(`.child-of-${uuid}`); @@ -397,6 +390,7 @@ JobsIndexController.$inject = [ '$filter', '$q', '$scope', + '$state', 'resource', 'JobPageService', 'JobScrollService', diff --git a/awx/ui/client/features/output/render.service.js b/awx/ui/client/features/output/render.service.js index 08a3498fd2..3f315a1ac0 100644 --- a/awx/ui/client/features/output/render.service.js +++ b/awx/ui/client/features/output/render.service.js @@ -30,11 +30,13 @@ const re = new RegExp(pattern); const hasAnsi = input => re.test(input); function JobRenderService ($q, $sce, $window) { - this.init = ({ compile, isStreamActive }) => { + this.init = ({ compile }) => { this.parent = null; this.record = {}; this.el = $(ELEMENT_TBODY); - this.hooks = { isStreamActive, compile }; + this.hooks = { compile }; + + this.createToggles = false; }; this.sortByLineNumber = (a, b) => { @@ -55,12 +57,11 @@ function JobRenderService ($q, $sce, $window) { events.sort(this.sortByLineNumber); - events.forEach(event => { - const line = this.transformEvent(event); - + for (let i = 0; i < events.length; ++i) { + const line = this.transformEvent(events[i]); html += line.html; lines += line.count; - }); + } return { html, lines }; }; @@ -177,13 +178,13 @@ function JobRenderService ($q, $sce, $window) { } if (current) { - if (!this.hooks.isStreamActive() && current.isParent && current.line === ln) { + if (this.createToggles && current.isParent && current.line === ln) { id = current.uuid; tdToggle = ``; } if (current.isHost) { - tdEvent = `${content}`; + tdEvent = `${content}`; } if (current.time && current.line === ln) { @@ -239,18 +240,7 @@ function JobRenderService ($q, $sce, $window) { return list; }; - this.insert = (events, insert) => { - const result = this.transformEventGroup(events); - const html = this.trustHtml(result.html); - - return this.requestAnimationFrame(() => insert(html)) - .then(() => this.compile(html)) - .then(() => result.lines); - }; - - this.remove = elements => this.requestAnimationFrame(() => { - elements.remove(); - }); + this.remove = elements => this.requestAnimationFrame(() => elements.remove()); this.requestAnimationFrame = fn => $q(resolve => { $window.requestAnimationFrame(() => { @@ -262,9 +252,8 @@ function JobRenderService ($q, $sce, $window) { }); }); - this.compile = html => { - html = $(this.el); - this.hooks.compile(html); + this.compile = content => { + this.hooks.compile(content); return this.requestAnimationFrame(); }; @@ -286,9 +275,35 @@ function JobRenderService ($q, $sce, $window) { return this.remove(elements); }; - this.prepend = events => this.insert(events, html => this.el.prepend(html)); + this.prepend = events => { + if (events.length < 1) { + return $q.resolve(); + } - this.append = events => this.insert(events, html => this.el.append(html)); + const result = this.transformEventGroup(events); + const html = this.trustHtml(result.html); + + const newElements = angular.element(html); + + return this.requestAnimationFrame(() => this.el.prepend(newElements)) + .then(() => this.compile(newElements)) + .then(() => result.lines); + }; + + this.append = events => { + if (events.length < 1) { + return $q.resolve(); + } + + const result = this.transformEventGroup(events); + const html = this.trustHtml(result.html); + + const newElements = angular.element(html); + + return this.requestAnimationFrame(() => this.el.append(newElements)) + .then(() => this.compile(newElements)) + .then(() => result.lines); + }; this.trustHtml = html => $sce.getTrustedHtml($sce.trustAsHtml(html));