Better reconnect after invalid lastKnownHash

pull/1/head
yflory 5 years ago
parent d53e9cff02
commit 578042154e

@ -424,7 +424,7 @@ const storeMessage = function (Env, channel, msg, isCp, optionalMessageHash) {
* it has a side-effect of filling the index cache if it's empty
1. if you provided a lastKnownHash and that message does not exist in the history:
* either the client has made a mistake or the history they knew about no longer exists
* call back with EINVAL
* call back with EUNKNOWN
2. if you did not provide a lastKnownHash
* and there are fewer than two checkpoints:
* return 0 (read from the start of the file)
@ -460,7 +460,7 @@ const getHistoryOffset = (Env, channelName, lastKnownHash, cb) => {
// QUESTION: does this mean mailboxes are causing the server to store too much stuff in memory?
if (lastKnownHash && typeof(lkh) !== "number") {
waitFor.abort();
return void cb(new Error('EINVAL'));
return void cb(new Error('EUNKNOWN'));
}
// Since last 2 checkpoints

@ -1499,6 +1499,15 @@ define([
return;
}
var onError = function (err) {
console.warn(err); // XXX DEBUG
channel.bcast("PAD_ERROR", err);
// If this is a DELETED, EXPIRED or RESTRICTED pad, leave the channel
if (["EDELETED", "EEXPIRED", "ERESTRICTED"].indexOf(err.type) === -1) { return; }
Store.leavePad(null, data, function () {});
};
var conf = {
onReady: function (pad) {
var padData = pad.metadata || {};
@ -1522,18 +1531,8 @@ define([
onLeave: function (m) {
channel.bcast("PAD_LEAVE", m);
},
onError: function (err) {
console.error(err); // XXX DEBUG
channel.bcast("PAD_ERROR", err);
Store.leavePad(null, data, function () {});
},
onChannelError: function (err) {
console.warn(err); // XXX DEBUG
channel.bcast("PAD_ERROR", err);
Store.leavePad(null, data, function () {});
},
onError: onError,
onChannelError: onError,
onRejected: function (allowed, _cb) {
var cb = Util.once(Util.mkAsync(_cb));

@ -325,6 +325,11 @@ define([
UI.updateLoadingProgress({ state: -1 }, false);
if (toolbar) {
// Check if we have a new chainpad instance
toolbar.resetChainpad(cpNfInner.chainpad);
}
var newPad = false;
if (newContentStr === '') { newPad = true; }
@ -364,6 +369,9 @@ define([
}).nThen(function () {
stateChange(STATE.READY);
firstConnection = false;
oldContent = undefined;
if (!readOnly) { onLocal(); }
evOnReady.fire(newPad);

@ -49,24 +49,29 @@ define([
config = undefined;
var evPatchSent = Util.mkEvent();
var chainpad;
var chainpad = ChainPad.create({
userName: userName,
initialState: initialState,
patchTransformer: patchTransformer,
validateContent: validateContent,
avgSyncMilliseconds: avgSyncMilliseconds,
logLevel: logLevel
});
chainpad.onMessage(function(message, cb) {
sframeChan.query('Q_RT_MESSAGE', message, function (err) {
if (!err) { evPatchSent.fire(); }
cb(err);
var makeChainPad = function () {
var _chainpad = ChainPad.create({
userName: userName,
initialState: initialState,
patchTransformer: patchTransformer,
validateContent: validateContent,
avgSyncMilliseconds: avgSyncMilliseconds,
logLevel: logLevel
});
});
chainpad.onPatch(function () {
onRemote({ realtime: chainpad });
});
_chainpad.onMessage(function(message, cb) {
sframeChan.query('Q_RT_MESSAGE', message, function (err) {
if (!err) { evPatchSent.fire(); }
cb(err);
});
});
_chainpad.onPatch(function () {
onRemote({ realtime: chainpad });
});
return _chainpad;
};
chainpad = makeChainPad();
var myID;
var isReady = false;
@ -96,6 +101,11 @@ define([
sframeChan.on('EV_RT_ERROR', function (err) {
isReady = false;
chainpad.abort();
if (err.type === 'EUNKNOWN') { // XXX
// Recoverable error: make a new chainpad
chainpad = makeChainPad();
return;
}
onError(err);
});
sframeChan.on('EV_RT_CONNECT', function (content) {
@ -149,15 +159,18 @@ define([
});
};
return Object.freeze({
var cpNfInner = {
getMyID: function () { return myID; },
metadataMgr: metadataMgr,
whenRealtimeSyncs: whenRealtimeSyncs,
onInfiniteSpinner: evInfiniteSpinner.reg,
onPatchSent: evPatchSent.reg,
offPatchSent: evPatchSent.unreg,
chainpad: chainpad,
};
cpNfInner.__defineGetter__("chainpad", function () {
return chainpad;
});
return Object.freeze(cpNfInner);
};
return Object.freeze(module.exports);
});

@ -1331,6 +1331,15 @@ MessengerUI, Messages) {
showColors = true;
};
// If we had to create a new chainpad instance, reset the one used in the toolbar
toolbar.resetChainpad = function (chainpad) {
if (config.realtime !== chainpad) {
config.realtime = chainpad;
config.realtime.onPatch(ks(toolbar, config));
config.realtime.onMessage(ks(toolbar, config, true));
}
};
// On log out, remove permanently the realtime elements of the toolbar
Common.onLogout(function () {
failed();

@ -794,6 +794,11 @@ define([
var userDoc = JSON.stringify(proxy);
if (userDoc === "" || userDoc === "{}") { isNew = true; }
if (APP.toolbar && APP.rt.cpCnInner) {
// Check if we have a new chainpad instance
APP.toolbar.resetChainpad(APP.rt.cpCnInner.chainpad);
}
if (!isNew) {
if (proxy.info) {
// Migration

Loading…
Cancel
Save