mirror of https://github.com/calzoneman/sync.git
Add dirty check to playlist for efficiency of channel saving
This commit is contained in:
parent
a4e72a002a
commit
0c330a82ce
|
@ -2,7 +2,7 @@
|
||||||
"author": "Calvin Montgomery",
|
"author": "Calvin Montgomery",
|
||||||
"name": "CyTube",
|
"name": "CyTube",
|
||||||
"description": "Online media synchronizer and chat",
|
"description": "Online media synchronizer and chat",
|
||||||
"version": "3.51.12",
|
"version": "3.51.13",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "http://github.com/calzoneman/sync"
|
"url": "http://github.com/calzoneman/sync"
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,10 +10,18 @@ const loadRowcount = new Counter({
|
||||||
name: 'cytube_channel_db_load_rows_total',
|
name: 'cytube_channel_db_load_rows_total',
|
||||||
help: 'Total rows loaded from the channel_data table'
|
help: 'Total rows loaded from the channel_data table'
|
||||||
});
|
});
|
||||||
|
const loadCharcount = new Counter({
|
||||||
|
name: 'cytube_channel_db_load_chars_total',
|
||||||
|
help: 'Total characters (JSON length) loaded from the channel_data table'
|
||||||
|
});
|
||||||
const saveRowcount = new Counter({
|
const saveRowcount = new Counter({
|
||||||
name: 'cytube_channel_db_save_rows_total',
|
name: 'cytube_channel_db_save_rows_total',
|
||||||
help: 'Total rows saved in the channel_data table'
|
help: 'Total rows saved in the channel_data table'
|
||||||
});
|
});
|
||||||
|
const saveCharcount = new Counter({
|
||||||
|
name: 'cytube_channel_db_save_chars_total',
|
||||||
|
help: 'Total characters (JSON length) saved in the channel_data table'
|
||||||
|
});
|
||||||
|
|
||||||
function queryAsync(query, substitutions) {
|
function queryAsync(query, substitutions) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -54,6 +62,7 @@ export class DatabaseStore {
|
||||||
rows.forEach(row => {
|
rows.forEach(row => {
|
||||||
try {
|
try {
|
||||||
data[row.key] = JSON.parse(row.value);
|
data[row.key] = JSON.parse(row.value);
|
||||||
|
loadCharcount.inc(row.value.length);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
LOGGER.error(`Channel data for channel "${channelName}", ` +
|
LOGGER.error(`Channel data for channel "${channelName}", ` +
|
||||||
`key "${row.key}" is invalid: ${e}`);
|
`key "${row.key}" is invalid: ${e}`);
|
||||||
|
@ -95,8 +104,6 @@ export class DatabaseStore {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveRowcount.inc(rowCount);
|
|
||||||
|
|
||||||
if (totalSize > SIZE_LIMIT) {
|
if (totalSize > SIZE_LIMIT) {
|
||||||
throw new ChannelStateSizeError(
|
throw new ChannelStateSizeError(
|
||||||
'Channel state size is too large', {
|
'Channel state size is too large', {
|
||||||
|
@ -105,6 +112,9 @@ export class DatabaseStore {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveRowcount.inc(rowCount);
|
||||||
|
saveCharcount.inc(totalSize);
|
||||||
|
|
||||||
return await queryAsync(buildUpdateQuery(rowCount), substitutions);
|
return await queryAsync(buildUpdateQuery(rowCount), substitutions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import Promise from 'bluebird';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { throttle } from '../util/throttle';
|
import { throttle } from '../util/throttle';
|
||||||
import Logger from '../logger';
|
import Logger from '../logger';
|
||||||
import * as Switches from '../switches';
|
|
||||||
|
|
||||||
const LOGGER = require('@calzoneman/jsli')('channel');
|
const LOGGER = require('@calzoneman/jsli')('channel');
|
||||||
|
|
||||||
|
@ -260,7 +259,6 @@ Channel.prototype.saveState = async function () {
|
||||||
Object.keys(this.modules).forEach(m => {
|
Object.keys(this.modules).forEach(m => {
|
||||||
if (
|
if (
|
||||||
this.modules[m].dirty ||
|
this.modules[m].dirty ||
|
||||||
!Switches.isActive('dirtyCheck') ||
|
|
||||||
!this.modules[m].supportsDirtyCheck
|
!this.modules[m].supportsDirtyCheck
|
||||||
) {
|
) {
|
||||||
this.modules[m].save(data);
|
this.modules[m].save(data);
|
||||||
|
|
|
@ -10,6 +10,7 @@ var CustomEmbedFilter = require("../customembed").filter;
|
||||||
var XSS = require("../xss");
|
var XSS = require("../xss");
|
||||||
import counters from '../counters';
|
import counters from '../counters';
|
||||||
import { Counter } from 'prom-client';
|
import { Counter } from 'prom-client';
|
||||||
|
import * as Switches from '../switches';
|
||||||
|
|
||||||
const LOGGER = require('@calzoneman/jsli')('playlist');
|
const LOGGER = require('@calzoneman/jsli')('playlist');
|
||||||
|
|
||||||
|
@ -107,19 +108,45 @@ function PlaylistModule(channel) {
|
||||||
this.channel.modules.chat.registerCommand("/clean", this.handleClean.bind(this));
|
this.channel.modules.chat.registerCommand("/clean", this.handleClean.bind(this));
|
||||||
this.channel.modules.chat.registerCommand("/cleantitle", this.handleClean.bind(this));
|
this.channel.modules.chat.registerCommand("/cleantitle", this.handleClean.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.supportsDirtyCheck = true;
|
||||||
|
this._positionDirty = false;
|
||||||
|
this._listDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaylistModule.prototype = Object.create(ChannelModule.prototype);
|
PlaylistModule.prototype = Object.create(ChannelModule.prototype);
|
||||||
|
|
||||||
|
Object.defineProperty(PlaylistModule.prototype, "dirty", {
|
||||||
|
get() {
|
||||||
|
return this._positionDirty || this._listDirty || !Switches.isActive("plDirtyCheck");
|
||||||
|
},
|
||||||
|
|
||||||
|
set(val) {
|
||||||
|
this._positionDirty = this._listDirty = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
PlaylistModule.prototype.load = function (data) {
|
PlaylistModule.prototype.load = function (data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var playlist = data.playlist;
|
let { playlist, playlistPosition } = data;
|
||||||
if (typeof playlist !== "object" || !("pl" in playlist)) {
|
|
||||||
|
if (typeof playlist !== "object" || !playlist.hasOwnProperty("pl")) {
|
||||||
|
LOGGER.warn(
|
||||||
|
"Bad playlist for channel %s",
|
||||||
|
self.channel.uniqueName
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var i = 0;
|
if (!playlistPosition) {
|
||||||
playlist.pos = parseInt(playlist.pos);
|
// Old style playlist
|
||||||
|
playlistPosition = {
|
||||||
|
index: playlist.pos,
|
||||||
|
time: playlist.time
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
playlist.pl.forEach(function (item) {
|
playlist.pl.forEach(function (item) {
|
||||||
if (item.media.type === "cu" && item.media.id.indexOf("cu:") !== 0) {
|
if (item.media.type === "cu" && item.media.id.indexOf("cu:") !== 0) {
|
||||||
try {
|
try {
|
||||||
|
@ -142,14 +169,15 @@ PlaylistModule.prototype.load = function (data) {
|
||||||
self.items.append(newitem);
|
self.items.append(newitem);
|
||||||
self.meta.count++;
|
self.meta.count++;
|
||||||
self.meta.rawTime += m.seconds;
|
self.meta.rawTime += m.seconds;
|
||||||
if (playlist.pos === i) {
|
if (playlistPosition.index === i) {
|
||||||
self.current = newitem;
|
self.current = newitem;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
|
|
||||||
self.meta.time = util.formatTime(self.meta.rawTime);
|
self.meta.time = util.formatTime(self.meta.rawTime);
|
||||||
self.startPlayback(playlist.time);
|
self.startPlayback(playlistPosition.time);
|
||||||
|
self.dirty = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
PlaylistModule.prototype.save = function (data) {
|
PlaylistModule.prototype.save = function (data) {
|
||||||
|
@ -167,11 +195,18 @@ PlaylistModule.prototype.save = function (data) {
|
||||||
time = this.current.media.currentTime;
|
time = this.current.media.currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.playlist = {
|
if (Switches.isActive("plDirtyCheck")) {
|
||||||
pl: arr,
|
data.playlistPosition = {
|
||||||
pos: pos,
|
index: pos,
|
||||||
time: time
|
time
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this._listDirty) {
|
||||||
|
data.playlist = { pl: arr };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data.playlist = { pl: arr, pos, time };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PlaylistModule.prototype.unload = function () {
|
PlaylistModule.prototype.unload = function () {
|
||||||
|
@ -585,6 +620,7 @@ PlaylistModule.prototype.handleSetTemp = function (user, data) {
|
||||||
|
|
||||||
item.temp = data.temp;
|
item.temp = data.temp;
|
||||||
this.channel.broadcastAll("setTemp", data);
|
this.channel.broadcastAll("setTemp", data);
|
||||||
|
this._listDirty = true;
|
||||||
|
|
||||||
if (!data.temp && this.channel.modules.library) {
|
if (!data.temp && this.channel.modules.library) {
|
||||||
this.channel.modules.library.cacheMedia(item.media);
|
this.channel.modules.library.cacheMedia(item.media);
|
||||||
|
@ -633,6 +669,7 @@ PlaylistModule.prototype.handleMoveMedia = function (user, data) {
|
||||||
self.channel.logger.log("[playlist] " + user.getName() + " moved " +
|
self.channel.logger.log("[playlist] " + user.getName() + " moved " +
|
||||||
from.media.title +
|
from.media.title +
|
||||||
(after ? " after " + after.media.title : ""));
|
(after ? " after " + after.media.title : ""));
|
||||||
|
self._listDirty = true;
|
||||||
lock.release();
|
lock.release();
|
||||||
self.channel.refCounter.unref("PlaylistModule::handleMoveMedia");
|
self.channel.refCounter.unref("PlaylistModule::handleMoveMedia");
|
||||||
});
|
});
|
||||||
|
@ -698,6 +735,8 @@ PlaylistModule.prototype.handleClear = function (user) {
|
||||||
|
|
||||||
this.channel.broadcastAll("playlist", []);
|
this.channel.broadcastAll("playlist", []);
|
||||||
this.channel.broadcastAll("setPlaylistMeta", this.meta);
|
this.channel.broadcastAll("setPlaylistMeta", this.meta);
|
||||||
|
this._listDirty = true;
|
||||||
|
this._positionDirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
PlaylistModule.prototype.handleShuffle = function (user) {
|
PlaylistModule.prototype.handleShuffle = function (user) {
|
||||||
|
@ -721,6 +760,8 @@ PlaylistModule.prototype.handleShuffle = function (user) {
|
||||||
this.items.append(item);
|
this.items.append(item);
|
||||||
pl.splice(i, 1);
|
pl.splice(i, 1);
|
||||||
}
|
}
|
||||||
|
this._listDirty = true;
|
||||||
|
this._positionDirty = true;
|
||||||
|
|
||||||
this.current = this.items.first;
|
this.current = this.items.first;
|
||||||
pl = this.items.toArray(true);
|
pl = this.items.toArray(true);
|
||||||
|
@ -821,6 +862,7 @@ PlaylistModule.prototype.handleUpdate = function (user, data) {
|
||||||
media.currentTime = data.currentTime;
|
media.currentTime = data.currentTime;
|
||||||
media.paused = Boolean(data.paused);
|
media.paused = Boolean(data.paused);
|
||||||
var update = media.getTimeUpdate();
|
var update = media.getTimeUpdate();
|
||||||
|
this._positionDirty = true;
|
||||||
|
|
||||||
this.channel.broadcastAll("mediaUpdate", update);
|
this.channel.broadcastAll("mediaUpdate", update);
|
||||||
};
|
};
|
||||||
|
@ -860,6 +902,8 @@ PlaylistModule.prototype._delete = function (uid) {
|
||||||
self.startPlayback();
|
self.startPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._listDirty = true;
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -976,6 +1020,8 @@ PlaylistModule.prototype._addItem = function (media, data, user, cb) {
|
||||||
self.startPlayback();
|
self.startPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._listDirty = true;
|
||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
cb();
|
cb();
|
||||||
}
|
}
|
||||||
|
@ -1016,6 +1062,7 @@ PlaylistModule.prototype.startPlayback = function (time) {
|
||||||
|
|
||||||
var media = self.current.media;
|
var media = self.current.media;
|
||||||
media.reset();
|
media.reset();
|
||||||
|
self._positionDirty = true;
|
||||||
|
|
||||||
if (self.leader != null) {
|
if (self.leader != null) {
|
||||||
media.paused = false;
|
media.paused = false;
|
||||||
|
@ -1094,6 +1141,8 @@ PlaylistModule.prototype._leadLoop = function() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._positionDirty = true;
|
||||||
|
|
||||||
var dt = (Date.now() - this._lastUpdate) / 1000.0;
|
var dt = (Date.now() - this._lastUpdate) / 1000.0;
|
||||||
var t = this.current.media.currentTime;
|
var t = this.current.media.currentTime;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue