Cache channel ID for quicker loads/saves

This commit is contained in:
Calvin Montgomery 2016-09-26 22:20:58 -07:00
parent b4b23f748f
commit e1120455b2
8 changed files with 47 additions and 85 deletions

View File

@ -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.22.1", "version": "3.22.2",
"repository": { "repository": {
"url": "http://github.com/calzoneman/sync" "url": "http://github.com/calzoneman/sync"
}, },

View File

@ -9,20 +9,20 @@ export function init() {
CHANNEL_STORE = loadChannelStore(); CHANNEL_STORE = loadChannelStore();
} }
export function load(channelName) { export function load(id, channelName) {
if (CHANNEL_STORE === null) { if (CHANNEL_STORE === null) {
return Promise.reject(new Error('ChannelStore not initialized yet')); return Promise.reject(new Error('ChannelStore not initialized yet'));
} }
return CHANNEL_STORE.load(channelName); return CHANNEL_STORE.load(id, channelName);
} }
export function save(channelName, data) { export function save(id, channelName, data) {
if (CHANNEL_STORE === null) { if (CHANNEL_STORE === null) {
return Promise.reject(new Error('ChannelStore not initialized yet')); return Promise.reject(new Error('ChannelStore not initialized yet'));
} }
return CHANNEL_STORE.save(channelName, data); return CHANNEL_STORE.save(id, channelName, data);
} }
function loadChannelStore() { function loadChannelStore() {

View File

@ -34,14 +34,13 @@ function buildUpdateQuery(numEntries) {
} }
export class DatabaseStore { export class DatabaseStore {
load(channelName) { load(id, channelName) {
return queryAsync(QUERY_CHANNEL_ID_FOR_NAME, [channelName]).then((rows) => { if (!id || id === 0) {
if (rows.length === 0) { return Promise.reject(new Error(`Cannot load state for [${channelName}]: ` +
throw new ChannelNotFoundError(`Channel does not exist: "${channelName}"`); `id was passed as [${id}]`));
} }
return queryAsync(QUERY_CHANNEL_DATA, [rows[0].id]); return queryAsync(QUERY_CHANNEL_DATA, [id]).then(rows => {
}).then(rows => {
const data = {}; const data = {};
rows.forEach(row => { rows.forEach(row => {
try { try {
@ -56,15 +55,14 @@ export class DatabaseStore {
}); });
} }
save(channelName, data) { save(id, channelName, data) {
return queryAsync(QUERY_CHANNEL_ID_FOR_NAME, [channelName]).then((rows) => { if (!id || id === 0) {
if (rows.length === 0) { return Promise.reject(new Error(`Cannot save state for [${channelName}]: ` +
throw new ChannelNotFoundError(`Channel does not exist: "${channelName}"`); `id was passed as [${id}]`));
} }
let totalSize = 0; let totalSize = 0;
let rowCount = 0; let rowCount = 0;
const id = rows[0].id;
const substitutions = []; const substitutions = [];
for (const key in data) { for (const key in data) {
if (typeof data[key] === 'undefined') { if (typeof data[key] === 'undefined') {
@ -86,6 +84,5 @@ export class DatabaseStore {
} }
return queryAsync(buildUpdateQuery(rowCount), substitutions); return queryAsync(buildUpdateQuery(rowCount), substitutions);
});
} }
} }

View File

@ -16,7 +16,7 @@ export class FileStore {
return path.join(CHANDUMP_DIR, channelName); return path.join(CHANDUMP_DIR, channelName);
} }
load(channelName) { load(id, channelName) {
const filename = this.filenameForChannel(channelName); const filename = this.filenameForChannel(channelName);
return statAsync(filename).then(stats => { return statAsync(filename).then(stats => {
if (stats.size > SIZE_LIMIT) { if (stats.size > SIZE_LIMIT) {
@ -36,7 +36,7 @@ export class FileStore {
}); });
} }
save(channelName, data) { save(id, channelName, data) {
const filename = this.filenameForChannel(channelName); const filename = this.filenameForChannel(channelName);
const fileContents = new Buffer(JSON.stringify(data), 'utf8'); const fileContents = new Buffer(JSON.stringify(data), 'utf8');
if (fileContents.length > SIZE_LIMIT) { if (fileContents.length > SIZE_LIMIT) {

View File

@ -84,6 +84,7 @@ function Channel(name) {
this.users = []; this.users = [];
this.refCounter = new ReferenceCounter(this); this.refCounter = new ReferenceCounter(this);
this.flags = 0; this.flags = 0;
this.id = 0;
this.broadcastUsercount = throttle(() => { this.broadcastUsercount = throttle(() => {
this.broadcastAll("usercount", this.users.length); this.broadcastAll("usercount", this.users.length);
}, USERCOUNT_THROTTLE); }, USERCOUNT_THROTTLE);
@ -206,7 +207,7 @@ Channel.prototype.loadState = function () {
self.setFlag(Flags.C_READY | Flags.C_ERROR); self.setFlag(Flags.C_READY | Flags.C_ERROR);
} }
ChannelStore.load(this.uniqueName).then(data => { ChannelStore.load(this.id, this.uniqueName).then(data => {
Object.keys(this.modules).forEach(m => { Object.keys(this.modules).forEach(m => {
try { try {
this.modules[m].load(data); this.modules[m].load(data);
@ -260,7 +261,8 @@ Channel.prototype.saveState = function () {
this.modules[m].save(data); this.modules[m].save(data);
}); });
return ChannelStore.save(this.uniqueName, data).catch(ChannelStateSizeError, err => { return ChannelStore.save(this.id, this.uniqueName, data)
.catch(ChannelStateSizeError, err => {
this.users.forEach(u => { this.users.forEach(u => {
if (u.account.effectiveRank >= 2) { if (u.account.effectiveRank >= 2) {
u.socket.emit("warnLargeChandump", { u.socket.emit("warnLargeChandump", {

View File

@ -80,6 +80,10 @@ module.exports.query = function (query, sub, callback) {
Metrics.stopTimer(timer); Metrics.stopTimer(timer);
} }
if (process.env.SHOW_SQL) {
console.log(query);
}
if (sub) { if (sub) {
conn.query(query, sub, cback); conn.query(query, sub, cback);
} else { } else {

View File

@ -232,48 +232,6 @@ module.exports = {
}); });
}, },
/**
* Verify an auth string of the form name:hash
*/
verifyAuth: function (auth, callback) {
if (typeof callback !== "function") {
return;
}
if (typeof auth !== "string") {
callback("Invalid auth string", null);
return;
}
var split = auth.split(":");
if (split.length !== 2) {
callback("Invalid auth string", null);
return;
}
var name = split[0];
var hash = split[1];
db.query("SELECT name,password,global_rank FROM `users` WHERE " +
"name=? and password=?", [name, hash],
function (err, rows) {
if (err) {
callback(err, null);
return;
}
if (rows.length === 0) {
callback("Auth string does not match an existing user", null);
return;
}
callback(null, {
name: rows[0].name,
hash: rows[0].password,
global_rank: rows[0].global_rank
});
});
},
/** /**
* Change a user's password * Change a user's password
*/ */

View File

@ -273,6 +273,7 @@ module.exports = {
// than the database has stored. Update accordingly. // than the database has stored. Update accordingly.
chan.name = res[0].name; chan.name = res[0].name;
chan.uniqueName = chan.name.toLowerCase(); chan.uniqueName = chan.name.toLowerCase();
chan.id = res[0].id;
chan.setFlag(Flags.C_REGISTERED); chan.setFlag(Flags.C_REGISTERED);
chan.logger.log("[init] Loaded channel from database"); chan.logger.log("[init] Loaded channel from database");
callback(null, true); callback(null, true);