Cut off terminal after 3000 lines
When autoscroll was disabled, terminal could run on endlessly, eating memory until the browser crashes. Now a hard upper limit ensures that not more than 3000 lines are ever stored in the terminal. If autoscroll is disabled and the limit is reached, no more log lines will be added. That ensures that the log will not scroll and the current log excerpt will stay put.
This commit is contained in:
parent
043b213a96
commit
40fe74ef45
2 changed files with 33 additions and 9 deletions
|
|
@ -7,6 +7,7 @@ $(function() {
|
|||
|
||||
self.log = ko.observableArray([]);
|
||||
self.buffer = ko.observable(300);
|
||||
self.upperLimit = ko.observable(3000);
|
||||
|
||||
self.command = ko.observable(undefined);
|
||||
|
||||
|
|
@ -52,13 +53,21 @@ $(function() {
|
|||
|
||||
self.lineCount = ko.computed(function() {
|
||||
var total = self.log().length;
|
||||
var filtered = _.filter(self.displayedLines(), function(entry) { return entry.type == "filtered" }).length;
|
||||
var displayed = _.filter(self.displayedLines(), function(entry) { return entry.type == "line" }).length;
|
||||
var filtered = total - displayed;
|
||||
|
||||
if (total == displayed) {
|
||||
return _.sprintf(gettext("showing %(displayed)d lines"), {displayed: displayed});
|
||||
if (filtered > 0) {
|
||||
if (total > self.upperLimit()) {
|
||||
return _.sprintf(gettext("showing %(displayed)d lines (%(filtered)d of %(total)d total lines filtered, buffer full)"), {displayed: displayed, total: total, filtered: filtered});
|
||||
} else {
|
||||
return _.sprintf(gettext("showing %(displayed)d lines (%(filtered)d of %(total)d total lines filtered)"), {displayed: displayed, total: total, filtered: filtered});
|
||||
}
|
||||
} else {
|
||||
return _.sprintf(gettext("showing %(displayed)d lines (%(filtered)d of %(total)d total lines filtered)"), {displayed: displayed, total: total, filtered: filtered});
|
||||
if (total > self.upperLimit()) {
|
||||
return _.sprintf(gettext("showing %(displayed)d lines (buffer full)"), {displayed: displayed});
|
||||
} else {
|
||||
return _.sprintf(gettext("showing %(displayed)d lines"), {displayed: displayed});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -84,10 +93,25 @@ $(function() {
|
|||
};
|
||||
|
||||
self._processCurrentLogData = function(data) {
|
||||
self.log(self.log().concat(_.map(data, function(line) { return self._toInternalFormat(line) })));
|
||||
if (self.autoscrollEnabled()) {
|
||||
self.log(self.log.slice(-self.buffer()));
|
||||
var length = self.log().length;
|
||||
if (length >= self.upperLimit()) {
|
||||
var cutoff = "--- too many lines to buffer, cut off ---";
|
||||
var last = self.log()[length-1];
|
||||
if (!last || last.type != "cut" || last.line != cutoff) {
|
||||
self.log(self.log().concat(self._toInternalFormat(cutoff, "cut")));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var newLog = self.log().concat(_.map(data, function(line) { return self._toInternalFormat(line) }));
|
||||
if (self.autoscrollEnabled()) {
|
||||
// we only keep the last <buffer> entries
|
||||
newLog = newLog.slice(-self.buffer());
|
||||
} else if (newLog.length > self.upperLimit()) {
|
||||
// we only keep the first <upperLimit> entries
|
||||
newLog = newLog.slice(0, self.upperLimit());
|
||||
}
|
||||
self.log(newLog);
|
||||
};
|
||||
|
||||
self._processHistoryLogData = function(data) {
|
||||
|
|
@ -232,4 +256,4 @@ $(function() {
|
|||
["loginStateViewModel", "settingsViewModel"],
|
||||
"#term"
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div class="terminal">
|
||||
<pre id="terminal-output" class="pre-scrollable" data-bind="foreach: displayedLines"><span data-bind="text: line, css: {muted: type == 'filtered'}"></span><br></pre>
|
||||
<pre id="terminal-output" class="pre-scrollable" data-bind="foreach: displayedLines"><span data-bind="text: line, css: {muted: type == 'filtered' || type == 'cut'}"></span><br></pre>
|
||||
<small class="pull-left"><button class="btn btn-mini" data-bind="click: toggleAutoscroll, css: {active: autoscrollEnabled}">{{ _('Autoscroll') }}</button> <span data-bind="text: lineCount"></span></small>
|
||||
<small class="pull-right"><a href="#" data-bind="click: scrollToEnd">{{ _("Scroll to end") }}</a> | <a href="#" data-bind="click: selectAll">{{ _("Select all") }}</a></small>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue