mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01:00 
			
		
		
		
	reload frontend when consistency is fixed
This commit is contained in:
		
							parent
							
								
									3f2ee4aefd
								
							
						
					
					
						commit
						9b9be5d155
					
				@ -50,6 +50,12 @@ function load() {
 | 
				
			|||||||
    log.info(`Becca (note cache) load took ${Date.now() - start}ms`);
 | 
					    log.info(`Becca (note cache) load took ${Date.now() - start}ms`);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function reload() {
 | 
				
			||||||
 | 
					    load();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    require('../services/ws').reloadFrontend();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function postProcessEntityUpdate(entityName, entity) {
 | 
					function postProcessEntityUpdate(entityName, entity) {
 | 
				
			||||||
    if (entityName === 'branches') {
 | 
					    if (entityName === 'branches') {
 | 
				
			||||||
        branchUpdated(entity);
 | 
					        branchUpdated(entity);
 | 
				
			||||||
@ -221,5 +227,6 @@ eventService.subscribe(eventService.LEAVE_PROTECTED_SESSION, load);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
    load,
 | 
					    load,
 | 
				
			||||||
 | 
					    reload,
 | 
				
			||||||
    beccaLoaded
 | 
					    beccaLoaded
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -47,6 +47,42 @@ function logRows(entityChanges) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function executeFrontendUpdate(entityChanges) {
 | 
				
			||||||
 | 
					    lastPingTs = Date.now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (entityChanges.length > 0) {
 | 
				
			||||||
 | 
					        logRows(entityChanges);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        frontendUpdateDataQueue.push(...entityChanges);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // we set lastAcceptedEntityChangeId even before frontend update processing and send ping so that backend can start sending more updates
 | 
				
			||||||
 | 
					        lastAcceptedEntityChangeId = Math.max(lastAcceptedEntityChangeId, entityChanges[entityChanges.length - 1].id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const lastSyncEntityChange = entityChanges.slice().reverse().find(ec => ec.isSynced);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (lastSyncEntityChange) {
 | 
				
			||||||
 | 
					            lastAcceptedEntityChangeSyncId = Math.max(lastAcceptedEntityChangeSyncId, lastSyncEntityChange.id);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sendPing();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // first wait for all the preceding consumers to finish
 | 
				
			||||||
 | 
					        while (consumeQueuePromise) {
 | 
				
			||||||
 | 
					            await consumeQueuePromise;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            // it's my turn so start it up
 | 
				
			||||||
 | 
					            consumeQueuePromise = consumeFrontendUpdateData();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await consumeQueuePromise;
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            // finish and set to null to signal somebody else can pick it up
 | 
				
			||||||
 | 
					            consumeQueuePromise = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function handleMessage(event) {
 | 
					async function handleMessage(event) {
 | 
				
			||||||
    const message = JSON.parse(event.data);
 | 
					    const message = JSON.parse(event.data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -54,42 +90,11 @@ async function handleMessage(event) {
 | 
				
			|||||||
        messageHandler(message);
 | 
					        messageHandler(message);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (message.type === 'frontend-update') {
 | 
					    if (message.type === 'reload-frontend') {
 | 
				
			||||||
        let {entityChanges} = message.data;
 | 
					        utils.reloadFrontendApp();
 | 
				
			||||||
        lastPingTs = Date.now();
 | 
					    }
 | 
				
			||||||
 | 
					    else if (message.type === 'frontend-update') {
 | 
				
			||||||
        if (entityChanges.length > 0) {
 | 
					        await executeFrontendUpdate(message.data.entityChanges);
 | 
				
			||||||
            logRows(entityChanges);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            frontendUpdateDataQueue.push(...entityChanges);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // we set lastAcceptedEntityChangeId even before frontend update processing and send ping so that backend can start sending more updates
 | 
					 | 
				
			||||||
            lastAcceptedEntityChangeId = Math.max(lastAcceptedEntityChangeId, entityChanges[entityChanges.length - 1].id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            const lastSyncEntityChange = entityChanges.slice().reverse().find(ec => ec.isSynced);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (lastSyncEntityChange) {
 | 
					 | 
				
			||||||
                lastAcceptedEntityChangeSyncId = Math.max(lastAcceptedEntityChangeSyncId, lastSyncEntityChange.id);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            sendPing();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // first wait for all the preceding consumers to finish
 | 
					 | 
				
			||||||
            while (consumeQueuePromise) {
 | 
					 | 
				
			||||||
                await consumeQueuePromise;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                // it's my turn so start it up
 | 
					 | 
				
			||||||
                consumeQueuePromise = consumeFrontendUpdateData();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                await consumeQueuePromise;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            finally {
 | 
					 | 
				
			||||||
                // finish and set to null to signal somebody else can pick it up
 | 
					 | 
				
			||||||
                consumeQueuePromise = null;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (message.type === 'sync-hash-check-failed') {
 | 
					    else if (message.type === 'sync-hash-check-failed') {
 | 
				
			||||||
        toastService.showError("Sync check failed!", 60000);
 | 
					        toastService.showError("Sync check failed!", 60000);
 | 
				
			||||||
@ -211,7 +216,6 @@ setTimeout(() => {
 | 
				
			|||||||
export default {
 | 
					export default {
 | 
				
			||||||
    logError,
 | 
					    logError,
 | 
				
			||||||
    subscribeToMessages,
 | 
					    subscribeToMessages,
 | 
				
			||||||
    waitForEntityChangeId,
 | 
					 | 
				
			||||||
    waitForMaxKnownEntityChangeId,
 | 
					    waitForMaxKnownEntityChangeId,
 | 
				
			||||||
    getMaxKnownEntityChangeSyncId: () => lastAcceptedEntityChangeSyncId
 | 
					    getMaxKnownEntityChangeSyncId: () => lastAcceptedEntityChangeSyncId
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -288,14 +288,17 @@ class ConsistencyChecks {
 | 
				
			|||||||
                    WHERE note_contents.noteId IS NULL`,
 | 
					                    WHERE note_contents.noteId IS NULL`,
 | 
				
			||||||
            ({noteId, isProtected, type, mime}) => {
 | 
					            ({noteId, isProtected, type, mime}) => {
 | 
				
			||||||
                if (this.autoFix) {
 | 
					                if (this.autoFix) {
 | 
				
			||||||
                    const utcDateModified = dateUtils.utcNowDateTime();
 | 
					                    // it might be possible that the note_content is not available only because of the interrupted
 | 
				
			||||||
 | 
					                    // sync and it will come later. It's therefore important to guarantee that this artifical
 | 
				
			||||||
 | 
					                    // record won't overwrite the real one coming from the sync.
 | 
				
			||||||
 | 
					                    const fakeDate = "2000-01-01 00:00:00Z";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // manually creating row since this can also affect deleted notes
 | 
					                    // manually creating row since this can also affect deleted notes
 | 
				
			||||||
                    sql.upsert("note_contents", "noteId", {
 | 
					                    sql.upsert("note_contents", "noteId", {
 | 
				
			||||||
                        noteId: noteId,
 | 
					                        noteId: noteId,
 | 
				
			||||||
                        content: getBlankContent(isProtected, type, mime),
 | 
					                        content: getBlankContent(isProtected, type, mime),
 | 
				
			||||||
                        utcDateModified: utcDateModified,
 | 
					                        utcDateModified: fakeDate,
 | 
				
			||||||
                        dateModified: dateUtils.localNowDateTime()
 | 
					                        dateModified: fakeDate
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const hash = utils.hash(utils.randomString(10));
 | 
					                    const hash = utils.hash(utils.randomString(10));
 | 
				
			||||||
@ -305,7 +308,7 @@ class ConsistencyChecks {
 | 
				
			|||||||
                        entityId: noteId,
 | 
					                        entityId: noteId,
 | 
				
			||||||
                        hash: hash,
 | 
					                        hash: hash,
 | 
				
			||||||
                        isErased: false,
 | 
					                        isErased: false,
 | 
				
			||||||
                        utcDateChanged: utcDateModified,
 | 
					                        utcDateChanged: fakeDate,
 | 
				
			||||||
                        isSynced: true
 | 
					                        isSynced: true
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -358,10 +361,11 @@ class ConsistencyChecks {
 | 
				
			|||||||
                      AND branches.isDeleted = 0`,
 | 
					                      AND branches.isDeleted = 0`,
 | 
				
			||||||
            ({parentNoteId}) => {
 | 
					            ({parentNoteId}) => {
 | 
				
			||||||
                if (this.autoFix) {
 | 
					                if (this.autoFix) {
 | 
				
			||||||
                    const branchIds = sql.getColumn(`SELECT branchId
 | 
					                    const branchIds = sql.getColumn(`
 | 
				
			||||||
                                                                   FROM branches
 | 
					                        SELECT branchId
 | 
				
			||||||
                                                                   WHERE isDeleted = 0
 | 
					                        FROM branches
 | 
				
			||||||
                                                                     AND parentNoteId = ?`, [parentNoteId]);
 | 
					                        WHERE isDeleted = 0
 | 
				
			||||||
 | 
					                          AND parentNoteId = ?`, [parentNoteId]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const branches = branchIds.map(branchId => becca.getBranch(branchId));
 | 
					                    const branches = branchIds.map(branchId => becca.getBranch(branchId));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -416,7 +420,7 @@ class ConsistencyChecks {
 | 
				
			|||||||
                    SELECT attributeId,
 | 
					                    SELECT attributeId,
 | 
				
			||||||
                           attributes.noteId
 | 
					                           attributes.noteId
 | 
				
			||||||
                    FROM attributes
 | 
					                    FROM attributes
 | 
				
			||||||
                      JOIN notes ON attributes.noteId = notes.noteId
 | 
					                    JOIN notes ON attributes.noteId = notes.noteId
 | 
				
			||||||
                    WHERE attributes.isDeleted = 0
 | 
					                    WHERE attributes.isDeleted = 0
 | 
				
			||||||
                      AND notes.isDeleted = 1`,
 | 
					                      AND notes.isDeleted = 1`,
 | 
				
			||||||
            ({attributeId, noteId}) => {
 | 
					            ({attributeId, noteId}) => {
 | 
				
			||||||
@ -434,7 +438,7 @@ class ConsistencyChecks {
 | 
				
			|||||||
                    SELECT attributeId,
 | 
					                    SELECT attributeId,
 | 
				
			||||||
                           attributes.value AS targetNoteId
 | 
					                           attributes.value AS targetNoteId
 | 
				
			||||||
                    FROM attributes
 | 
					                    FROM attributes
 | 
				
			||||||
                      JOIN notes ON attributes.value = notes.noteId
 | 
					                    JOIN notes ON attributes.value = notes.noteId
 | 
				
			||||||
                    WHERE attributes.type = 'relation'
 | 
					                    WHERE attributes.type = 'relation'
 | 
				
			||||||
                      AND attributes.isDeleted = 0
 | 
					                      AND attributes.isDeleted = 0
 | 
				
			||||||
                      AND notes.isDeleted = 1`,
 | 
					                      AND notes.isDeleted = 1`,
 | 
				
			||||||
@ -584,7 +588,7 @@ class ConsistencyChecks {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (this.fixedIssues) {
 | 
					        if (this.fixedIssues) {
 | 
				
			||||||
            require("../becca/becca_loader").load();
 | 
					            require("../becca/becca_loader").reload();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return !this.unrecoveredConsistencyErrors;
 | 
					        return !this.unrecoveredConsistencyErrors;
 | 
				
			||||||
 | 
				
			|||||||
@ -178,6 +178,10 @@ function syncFailed() {
 | 
				
			|||||||
    sendMessageToAllClients({ type: 'sync-failed', lastSyncedPush });
 | 
					    sendMessageToAllClients({ type: 'sync-failed', lastSyncedPush });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function reloadFrontend() {
 | 
				
			||||||
 | 
					    sendMessageToAllClients({ type: 'reload-frontend' });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function setLastSyncedPush(entityChangeId) {
 | 
					function setLastSyncedPush(entityChangeId) {
 | 
				
			||||||
    lastSyncedPush = entityChangeId;
 | 
					    lastSyncedPush = entityChangeId;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -190,5 +194,6 @@ module.exports = {
 | 
				
			|||||||
    syncFinished,
 | 
					    syncFinished,
 | 
				
			||||||
    syncFailed,
 | 
					    syncFailed,
 | 
				
			||||||
    sendTransactionEntityChangesToAllClients,
 | 
					    sendTransactionEntityChangesToAllClients,
 | 
				
			||||||
    setLastSyncedPush
 | 
					    setLastSyncedPush,
 | 
				
			||||||
 | 
					    reloadFrontend
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user