mirror of
https://github.com/ansible/awx.git
synced 2026-05-07 01:17:37 -02:30
add handling for discontinuities in render service
This commit is contained in:
@@ -102,6 +102,10 @@
|
|||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
border-right: 1px solid @at-gray-b7;
|
border-right: 1px solid @at-gray-b7;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
&-clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-event {
|
&-event {
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import Ansi from 'ansi-to-html';
|
import Ansi from 'ansi-to-html';
|
||||||
import Entities from 'html-entities';
|
import Entities from 'html-entities';
|
||||||
|
import getUUID from 'uuid';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EVENT_START_PLAY,
|
EVENT_START_PLAY,
|
||||||
EVENT_STATS_PLAY,
|
EVENT_STATS_PLAY,
|
||||||
EVENT_START_TASK,
|
EVENT_START_TASK,
|
||||||
OUTPUT_ELEMENT_TBODY,
|
OUTPUT_ELEMENT_TBODY,
|
||||||
|
OUTPUT_EVENT_LIMIT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
|
|
||||||
const EVENT_GROUPS = [
|
const EVENT_GROUPS = [
|
||||||
@@ -31,46 +33,71 @@ const pattern = [
|
|||||||
const re = new RegExp(pattern);
|
const re = new RegExp(pattern);
|
||||||
const hasAnsi = input => re.test(input);
|
const hasAnsi = input => re.test(input);
|
||||||
|
|
||||||
const MISSING_EVENT_GROUP = 'MISSING_EVENT_GROUP';
|
|
||||||
|
|
||||||
function JobRenderService ($q, $sce, $window) {
|
function JobRenderService ($q, $sce, $window) {
|
||||||
this.init = ({ compile, toggles }) => {
|
this.init = ({ compile, toggles }) => {
|
||||||
this.parent = null;
|
|
||||||
this.record = {};
|
|
||||||
this.el = $(OUTPUT_ELEMENT_TBODY);
|
|
||||||
this.hooks = { compile };
|
this.hooks = { compile };
|
||||||
|
|
||||||
this.createToggles = toggles;
|
this.el = $(OUTPUT_ELEMENT_TBODY);
|
||||||
this.lastMissing = false;
|
this.parent = null;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
collapseAll: false
|
head: null,
|
||||||
|
tail: null,
|
||||||
|
collapseAll: false,
|
||||||
|
toggleMode: toggles,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.counters = {};
|
||||||
|
this.lines = {};
|
||||||
|
this.records = {};
|
||||||
|
this.uuids = {};
|
||||||
|
|
||||||
|
this.missingCounterRecords = {};
|
||||||
|
this.missingCounterUUIDs = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setCollapseAll = value => {
|
this.setCollapseAll = value => {
|
||||||
this.state.collapseAll = value;
|
this.state.collapseAll = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.sortByLineNumber = (a, b) => {
|
this.sortByCounter = (a, b) => {
|
||||||
if (a.start_line > b.start_line) {
|
if (a.counter > b.counter) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.start_line < b.start_line) {
|
if (a.counter < b.counter) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.transformEventGroup = events => {
|
//
|
||||||
|
// Event Data Transformation / HTML Building
|
||||||
|
//
|
||||||
|
|
||||||
|
this.transformEventGroup = (events, streaming = false) => {
|
||||||
let lines = 0;
|
let lines = 0;
|
||||||
let html = '';
|
let html = '';
|
||||||
|
|
||||||
events.sort(this.sortByLineNumber);
|
events.sort(this.sortByCounter);
|
||||||
|
|
||||||
|
for (let i = 0; i <= events.length - 1; i++) {
|
||||||
|
const current = events[i];
|
||||||
|
|
||||||
|
if (streaming) {
|
||||||
|
const tailCounter = this.getTailCounter();
|
||||||
|
|
||||||
|
if (tailCounter && (current.counter !== tailCounter + 1)) {
|
||||||
|
const missing = this.transformMissingEventGroup(current);
|
||||||
|
|
||||||
|
html += missing.html;
|
||||||
|
lines += missing.count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const line = this.transformEvent(current);
|
||||||
|
|
||||||
for (let i = 0; i < events.length; ++i) {
|
|
||||||
const line = this.transformEvent(events[i]);
|
|
||||||
html += line.html;
|
html += line.html;
|
||||||
lines += line.count;
|
lines += line.count;
|
||||||
}
|
}
|
||||||
@@ -78,21 +105,42 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
return { html, lines };
|
return { html, lines };
|
||||||
};
|
};
|
||||||
|
|
||||||
this.transformEvent = event => {
|
this.transformMissingEventGroup = event => {
|
||||||
if (event.uuid && this.record[event.uuid]) {
|
const tail = this.lookupRecord(this.getTailCounter());
|
||||||
|
|
||||||
|
if (!tail || !tail.counter) {
|
||||||
return { html: '', count: 0 };
|
return { html: '', count: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.event === MISSING_EVENT_GROUP) {
|
const uuid = getUUID();
|
||||||
if (this.lastMissing) {
|
const counters = [];
|
||||||
return { html: '', count: 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lastMissing = true;
|
for (let i = tail.counter + 1; i < event.counter; i++) {
|
||||||
return this.transformMissingEvent(event);
|
counters.push(i);
|
||||||
|
this.missingCounterUUIDs[i] = uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastMissing = false;
|
const record = {
|
||||||
|
counters,
|
||||||
|
uuid,
|
||||||
|
start: tail.end,
|
||||||
|
end: event.start_line,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.missingCounterRecords[uuid] = record;
|
||||||
|
|
||||||
|
const html = `<div id="${uuid}" class="at-Stdout-row">
|
||||||
|
<div class="at-Stdout-toggle"></div>
|
||||||
|
<div class="at-Stdout-line-clickable" ng-click="vm.showMissingEvents('${uuid}')">...</div></div>`;
|
||||||
|
const count = 1;
|
||||||
|
|
||||||
|
return { html, count };
|
||||||
|
};
|
||||||
|
|
||||||
|
this.transformEvent = event => {
|
||||||
|
if (event.uuid && this.records[event.uuid]) {
|
||||||
|
return { html: '', count: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
if (!event || !event.stdout) {
|
if (!event || !event.stdout) {
|
||||||
return { html: '', count: 0 };
|
return { html: '', count: 0 };
|
||||||
@@ -100,59 +148,65 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
|
|
||||||
const stdout = this.sanitize(event.stdout);
|
const stdout = this.sanitize(event.stdout);
|
||||||
const lines = stdout.split('\r\n');
|
const lines = stdout.split('\r\n');
|
||||||
|
const record = this.createRecord(event, lines);
|
||||||
|
|
||||||
|
let html = '';
|
||||||
let count = lines.length;
|
let count = lines.length;
|
||||||
let ln = event.start_line;
|
let ln = event.start_line;
|
||||||
|
|
||||||
const current = this.createRecord(ln, lines, event);
|
for (let i = 0; i <= lines.length - 1; i++) {
|
||||||
|
|
||||||
const html = lines.reduce((concat, line, i) => {
|
|
||||||
ln++;
|
ln++;
|
||||||
|
|
||||||
|
const line = lines[i];
|
||||||
const isLastLine = i === lines.length - 1;
|
const isLastLine = i === lines.length - 1;
|
||||||
|
|
||||||
let row = this.createRow(current, ln, line);
|
let row = this.createRow(record, ln, line);
|
||||||
|
|
||||||
if (current && current.isTruncated && isLastLine) {
|
if (record && record.isTruncated && isLastLine) {
|
||||||
row += this.createRow(current);
|
row += this.createRow(record);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${concat}${row}`;
|
html += row;
|
||||||
}, '');
|
}
|
||||||
|
|
||||||
return { html, count };
|
return { html, count };
|
||||||
};
|
};
|
||||||
|
|
||||||
this.transformMissingEvent = () => {
|
this.createRecord = (event, lines) => {
|
||||||
const html = '<div class="at-Stdout-row"><div class="at-Stdout-line">...</div></div>';
|
if (!event.counter) {
|
||||||
const count = 1;
|
return null;
|
||||||
|
|
||||||
return { html, count };
|
|
||||||
};
|
|
||||||
|
|
||||||
this.isHostEvent = (event) => {
|
|
||||||
if (typeof event.host === 'number') {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.type === 'project_update_event' &&
|
this.lines[event.counter] = event.end_line - event.start_line;
|
||||||
event.event !== 'runner_on_skipped' &&
|
|
||||||
event.event_data.host) {
|
if (this.state.tail === null ||
|
||||||
return true;
|
this.state.tail < event.counter) {
|
||||||
|
this.state.tail = event.counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (this.state.head === null ||
|
||||||
};
|
this.state.head > event.counter) {
|
||||||
|
this.state.head = event.counter;
|
||||||
|
}
|
||||||
|
|
||||||
this.createRecord = (ln, lines, event) => {
|
|
||||||
if (!event.uuid) {
|
if (!event.uuid) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const info = {
|
let isHost = false;
|
||||||
|
if (typeof event.host === 'number') {
|
||||||
|
isHost = true;
|
||||||
|
} else if (event.type === 'project_update_event' &&
|
||||||
|
event.event !== 'runner_on_skipped' &&
|
||||||
|
event.event_data.host) {
|
||||||
|
isHost = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const record = {
|
||||||
|
isHost,
|
||||||
id: event.id,
|
id: event.id,
|
||||||
line: ln + 1,
|
line: event.start_line + 1,
|
||||||
name: event.event,
|
name: event.event,
|
||||||
uuid: event.uuid,
|
uuid: event.uuid,
|
||||||
level: event.event_level,
|
level: event.event_level,
|
||||||
@@ -160,54 +214,50 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
end: event.end_line,
|
end: event.end_line,
|
||||||
isTruncated: (event.end_line - event.start_line) > lines.length,
|
isTruncated: (event.end_line - event.start_line) > lines.length,
|
||||||
lineCount: lines.length,
|
lineCount: lines.length,
|
||||||
isHost: this.isHostEvent(event),
|
|
||||||
isCollapsed: this.state.collapseAll,
|
isCollapsed: this.state.collapseAll,
|
||||||
|
counter: event.counter,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (event.parent_uuid) {
|
if (event.parent_uuid) {
|
||||||
info.parents = this.getParentEvents(event.parent_uuid);
|
record.parents = this.getParentEvents(event.parent_uuid);
|
||||||
if (this.record[event.parent_uuid]) {
|
if (this.records[event.parent_uuid]) {
|
||||||
info.isCollapsed = this.record[event.parent_uuid].isCollapsed;
|
record.isCollapsed = this.records[event.parent_uuid].isCollapsed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.isTruncated) {
|
if (record.isTruncated) {
|
||||||
info.truncatedAt = event.start_line + lines.length;
|
record.truncatedAt = event.start_line + lines.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EVENT_GROUPS.includes(event.event)) {
|
if (EVENT_GROUPS.includes(event.event)) {
|
||||||
info.isParent = true;
|
record.isParent = true;
|
||||||
|
|
||||||
if (event.event_level === 1) {
|
if (event.event_level === 1) {
|
||||||
this.parent = event.uuid;
|
this.parent = event.uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.parent_uuid) {
|
if (event.parent_uuid) {
|
||||||
if (this.record[event.parent_uuid]) {
|
if (this.records[event.parent_uuid]) {
|
||||||
if (this.record[event.parent_uuid].children &&
|
if (this.records[event.parent_uuid].children &&
|
||||||
!this.record[event.parent_uuid].children.includes(event.uuid)) {
|
!this.records[event.parent_uuid].children.includes(event.uuid)) {
|
||||||
this.record[event.parent_uuid].children.push(event.uuid);
|
this.records[event.parent_uuid].children.push(event.uuid);
|
||||||
} else {
|
} else {
|
||||||
this.record[event.parent_uuid].children = [event.uuid];
|
this.records[event.parent_uuid].children = [event.uuid];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TIME_EVENTS.includes(event.event)) {
|
if (TIME_EVENTS.includes(event.event)) {
|
||||||
info.time = this.getTimestamp(event.created);
|
record.time = this.getTimestamp(event.created);
|
||||||
info.line++;
|
record.line++;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.record[event.uuid] = info;
|
this.uuids[event.counter] = record.uuid;
|
||||||
|
this.counters[event.uuid] = record.counter;
|
||||||
|
this.records[event.uuid] = record;
|
||||||
|
|
||||||
return info;
|
return record;
|
||||||
};
|
|
||||||
|
|
||||||
this.getRecord = uuid => this.record[uuid];
|
|
||||||
|
|
||||||
this.deleteRecord = uuid => {
|
|
||||||
delete this.record[uuid];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getParentEvents = (uuid, list) => {
|
this.getParentEvents = (uuid, list) => {
|
||||||
@@ -215,14 +265,32 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
// always push its parent if exists
|
// always push its parent if exists
|
||||||
list.push(uuid);
|
list.push(uuid);
|
||||||
// if we can get grandparent in current visible lines, we also push it
|
// if we can get grandparent in current visible lines, we also push it
|
||||||
if (this.record[uuid] && this.record[uuid].parents) {
|
if (this.records[uuid] && this.records[uuid].parents) {
|
||||||
list = list.concat(this.record[uuid].parents);
|
list = list.concat(this.records[uuid].parents);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.createRow = (current, ln, content) => {
|
this.deleteRecord = counter => {
|
||||||
|
const uuid = this.uuids[counter];
|
||||||
|
|
||||||
|
delete this.records[uuid];
|
||||||
|
delete this.counters[uuid];
|
||||||
|
delete this.uuids[counter];
|
||||||
|
delete this.lines[counter];
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getTimestamp = created => {
|
||||||
|
const date = new Date(created);
|
||||||
|
const hour = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours();
|
||||||
|
const minute = date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes();
|
||||||
|
const second = date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds();
|
||||||
|
|
||||||
|
return `${hour}:${minute}:${second}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.createRow = (record, ln, content) => {
|
||||||
let id = '';
|
let id = '';
|
||||||
let icon = '';
|
let icon = '';
|
||||||
let timestamp = '';
|
let timestamp = '';
|
||||||
@@ -236,11 +304,11 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
content = ansi.toHtml(content);
|
content = ansi.toHtml(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current) {
|
if (record) {
|
||||||
if (this.createToggles && current.isParent && current.line === ln) {
|
if (this.state.toggleMode && record.isParent && record.line === ln) {
|
||||||
id = current.uuid;
|
id = record.uuid;
|
||||||
|
|
||||||
if (current.isCollapsed) {
|
if (record.isCollapsed) {
|
||||||
icon = 'fa-angle-right';
|
icon = 'fa-angle-right';
|
||||||
} else {
|
} else {
|
||||||
icon = 'fa-angle-down';
|
icon = 'fa-angle-down';
|
||||||
@@ -249,16 +317,16 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
tdToggle = `<div class="at-Stdout-toggle" ng-click="vm.toggleCollapse('${id}')"><i class="fa ${icon} can-toggle"></i></div>`;
|
tdToggle = `<div class="at-Stdout-toggle" ng-click="vm.toggleCollapse('${id}')"><i class="fa ${icon} can-toggle"></i></div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.isHost) {
|
if (record.isHost) {
|
||||||
tdEvent = `<div class="at-Stdout-event--host" ng-click="vm.showHostDetails('${current.id}', '${current.uuid}')"><span ng-non-bindable>${content}</span></div>`;
|
tdEvent = `<div class="at-Stdout-event--host" ng-click="vm.showHostDetails('${record.id}', '${record.uuid}')"><span ng-non-bindable>${content}</span></div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.time && current.line === ln) {
|
if (record.time && record.line === ln) {
|
||||||
timestamp = `<span>${current.time}</span>`;
|
timestamp = `<span>${record.time}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.parents) {
|
if (record.parents) {
|
||||||
classList = current.parents.reduce((list, uuid) => `${list} child-of-${uuid}`, '');
|
classList = record.parents.reduce((list, uuid) => `${list} child-of-${uuid}`, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,8 +342,8 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
ln = '...';
|
ln = '...';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current && current.isCollapsed) {
|
if (record && record.isCollapsed) {
|
||||||
if (current.level === 3 || current.level === 0) {
|
if (record.level === 3 || record.level === 0) {
|
||||||
classList += ' hidden';
|
classList += ' hidden';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,14 +357,9 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
</div>`;
|
</div>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getTimestamp = created => {
|
//
|
||||||
const date = new Date(created);
|
// Element Operations
|
||||||
const hour = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours();
|
//
|
||||||
const minute = date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes();
|
|
||||||
const second = date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds();
|
|
||||||
|
|
||||||
return `${hour}:${minute}:${second}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.remove = elements => this.requestAnimationFrame(() => elements.remove());
|
this.remove = elements => this.requestAnimationFrame(() => elements.remove());
|
||||||
|
|
||||||
@@ -316,7 +379,7 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
return this.requestAnimationFrame();
|
return this.requestAnimationFrame();
|
||||||
};
|
};
|
||||||
|
|
||||||
this.clear = () => {
|
this.removeAll = () => {
|
||||||
const elements = this.el.children();
|
const elements = this.el.children();
|
||||||
return this.remove(elements);
|
return this.remove(elements);
|
||||||
};
|
};
|
||||||
@@ -348,12 +411,12 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
.then(() => result.lines);
|
.then(() => result.lines);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.append = events => {
|
this.append = (events, streaming = false) => {
|
||||||
if (events.length < 1) {
|
if (events.length < 1) {
|
||||||
return $q.resolve();
|
return $q.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = this.transformEventGroup(events);
|
const result = this.transformEventGroup(events, streaming);
|
||||||
const html = this.trustHtml(result.html);
|
const html = this.trustHtml(result.html);
|
||||||
|
|
||||||
const newElements = angular.element(html);
|
const newElements = angular.element(html);
|
||||||
@@ -364,8 +427,189 @@ function JobRenderService ($q, $sce, $window) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.trustHtml = html => $sce.getTrustedHtml($sce.trustAsHtml(html));
|
this.trustHtml = html => $sce.getTrustedHtml($sce.trustAsHtml(html));
|
||||||
|
|
||||||
this.sanitize = html => entities.encode(html);
|
this.sanitize = html => entities.encode(html);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Event Counter Methods - External code should use these.
|
||||||
|
//
|
||||||
|
|
||||||
|
this.getTailCounter = () => {
|
||||||
|
if (this.state.tail === null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.state.tail < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.state.tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getHeadCounter = () => {
|
||||||
|
if (this.state.head === null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.state.head < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.state.head;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getCapacity = () => OUTPUT_EVENT_LIMIT - Object.keys(this.lines).length;
|
||||||
|
|
||||||
|
this.lookupRecord = counter => this.records[this.uuids[counter]];
|
||||||
|
|
||||||
|
this.getLineCount = counter => {
|
||||||
|
const record = this.lookupRecord(counter);
|
||||||
|
|
||||||
|
if (record && record.lineCount) {
|
||||||
|
return record.lineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.lines[counter]) {
|
||||||
|
return this.lines[counter];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.deleteMissingCounterRecord = counter => {
|
||||||
|
const uuid = this.missingCounterUUIDs[counter];
|
||||||
|
|
||||||
|
delete this.missingCounterRecords[counter];
|
||||||
|
delete this.missingCounterUUIDs[uuid];
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clear = () => this.removeAll()
|
||||||
|
.then(() => {
|
||||||
|
const head = this.getHeadCounter();
|
||||||
|
const tail = this.getTailCounter();
|
||||||
|
|
||||||
|
for (let i = head; i <= tail; ++i) {
|
||||||
|
this.deleteRecord(i);
|
||||||
|
this.deleteMissingCounterRecord(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.head = null;
|
||||||
|
this.state.tail = null;
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.pushFront = (events, streaming = false) => {
|
||||||
|
const tail = this.getTailCounter();
|
||||||
|
|
||||||
|
return this.append(events.filter(({ counter }) => counter > tail), streaming);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.pushBack = events => {
|
||||||
|
const head = this.getHeadCounter();
|
||||||
|
const tail = this.getTailCounter();
|
||||||
|
|
||||||
|
return this.prepend(events.filter(({ counter }) => counter < head || counter > tail));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.pushFrames = events => this.pushFront(events, true);
|
||||||
|
|
||||||
|
this.popMissing = counter => {
|
||||||
|
const uuid = this.missingCounterUUIDs[counter];
|
||||||
|
|
||||||
|
if (!this.missingCounterRecords[uuid]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.missingCounterRecords[uuid].counters.pop();
|
||||||
|
|
||||||
|
if (this.missingCounterRecords[uuid].counters.length > 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.missingCounterRecords[uuid];
|
||||||
|
delete this.missingCounterUUIDs[counter];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.shiftMissing = counter => {
|
||||||
|
const uuid = this.missingCounterUUIDs[counter];
|
||||||
|
|
||||||
|
if (!this.missingCounterRecords[uuid]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.missingCounterRecords[uuid].counters.shift();
|
||||||
|
|
||||||
|
if (this.missingCounterRecords[uuid].counters.length > 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete this.missingCounterRecords[uuid];
|
||||||
|
delete this.missingCounterUUIDs[counter];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isCounterMissing = counter => this.missingCounterUUIDs[counter];
|
||||||
|
|
||||||
|
this.popFront = count => {
|
||||||
|
if (!count || count <= 0) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const max = this.getTailCounter();
|
||||||
|
const min = max - count;
|
||||||
|
|
||||||
|
let lines = 0;
|
||||||
|
|
||||||
|
for (let i = max; i >= min; --i) {
|
||||||
|
if (this.isCounterMissing(i)) {
|
||||||
|
lines += this.popMissing(i);
|
||||||
|
} else {
|
||||||
|
lines += this.getLineCount(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.pop(lines)
|
||||||
|
.then(() => {
|
||||||
|
for (let i = max; i >= min; --i) {
|
||||||
|
this.deleteRecord(i);
|
||||||
|
this.state.tail--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.popBack = count => {
|
||||||
|
if (!count || count <= 0) {
|
||||||
|
return $q.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
const min = this.getHeadCounter();
|
||||||
|
const max = min + count;
|
||||||
|
|
||||||
|
let lines = 0;
|
||||||
|
|
||||||
|
for (let i = min; i <= max; ++i) {
|
||||||
|
if (this.isCounterMissing(i)) {
|
||||||
|
lines += this.popMissing(i);
|
||||||
|
} else {
|
||||||
|
lines += this.getLineCount(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.shift(lines)
|
||||||
|
.then(() => {
|
||||||
|
for (let i = min; i <= max; ++i) {
|
||||||
|
this.deleteRecord(i);
|
||||||
|
this.state.head++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $q.resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
JobRenderService.$inject = ['$q', '$sce', '$window'];
|
JobRenderService.$inject = ['$q', '$sce', '$window'];
|
||||||
|
|||||||
Reference in New Issue
Block a user