Refactor database.service
This commit is contained in:
parent
aa22b78121
commit
b7a2f3a058
@ -8,6 +8,7 @@ export class Database {
|
||||
private serviceWorkerRegistration: ServiceWorkerRegistration | null = null;
|
||||
private messageChannel: MessageChannel | null = null;
|
||||
private messageChannelForGet: MessageChannel | null = null;
|
||||
private serviceWorkerCheckIntervalId: number | null = null;
|
||||
private storeDefinitions = {
|
||||
AnkLabels: {
|
||||
name: 'labels',
|
||||
@ -81,12 +82,10 @@ export class Database {
|
||||
});
|
||||
};
|
||||
|
||||
request.onsuccess = () => {
|
||||
setTimeout(() => {
|
||||
this.db = request.result;
|
||||
this.initServiceWorker();
|
||||
resolve();
|
||||
}, 500);
|
||||
request.onsuccess = async () => {
|
||||
this.db = request.result;
|
||||
await this.initServiceWorker();
|
||||
resolve();
|
||||
};
|
||||
|
||||
request.onerror = () => {
|
||||
@ -115,43 +114,43 @@ export class Database {
|
||||
if (!('serviceWorker' in navigator)) return; // Ensure service workers are supported
|
||||
|
||||
try {
|
||||
// Get existing service worker registrations
|
||||
const registrations = await navigator.serviceWorker.getRegistrations();
|
||||
if (registrations.length === 0) {
|
||||
// No existing workers: register a new one.
|
||||
this.serviceWorkerRegistration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' });
|
||||
console.log('Service Worker registered with scope:', registration.scope);
|
||||
} else if (registrations.length === 1) {
|
||||
// One existing worker: update it (restart it) without unregistering.
|
||||
this.serviceWorkerRegistration = registrations[0];
|
||||
await this.serviceWorkerRegistration.update();
|
||||
console.log('Service worker updated');
|
||||
} else {
|
||||
// More than one existing worker: unregister them all and register a new one.
|
||||
console.log('Multiple Service Worker(s) detected. Unregistering all...');
|
||||
await Promise.all(registrations.map(reg => reg.unregister()));
|
||||
console.log('All previous Service Workers unregistered.');
|
||||
this.serviceWorkerRegistration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' });
|
||||
console.log('Service Worker registered with scope:', registration.scope);
|
||||
}
|
||||
// Get existing service worker registrations
|
||||
const registrations = await navigator.serviceWorker.getRegistrations();
|
||||
if (registrations.length === 0) {
|
||||
// No existing workers: register a new one.
|
||||
this.serviceWorkerRegistration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' });
|
||||
console.log('Service Worker registered with scope:', this.serviceWorkerRegistration.scope);
|
||||
} else if (registrations.length === 1) {
|
||||
// One existing worker: update it (restart it) without unregistering.
|
||||
this.serviceWorkerRegistration = registrations[0];
|
||||
await this.serviceWorkerRegistration.update();
|
||||
console.log('Service Worker updated');
|
||||
} else {
|
||||
// More than one existing worker: unregister them all and register a new one.
|
||||
console.log('Multiple Service Worker(s) detected. Unregistering all...');
|
||||
await Promise.all(registrations.map(reg => reg.unregister()));
|
||||
console.log('All previous Service Workers unregistered.');
|
||||
this.serviceWorkerRegistration = await navigator.serviceWorker.register('/src/service-workers/database.worker.js', { type: 'module' });
|
||||
console.log('Service Worker registered with scope:', this.serviceWorkerRegistration.scope);
|
||||
}
|
||||
|
||||
await this.checkForUpdates();
|
||||
await this.checkForUpdates();
|
||||
|
||||
// Set up the message channels
|
||||
this.messageChannel = new MessageChannel();
|
||||
this.messageChannelForGet = new MessageChannel();
|
||||
this.messageChannel.port1.onmessage = this.handleAddObjectResponse;
|
||||
this.messageChannelForGet.port1.onmessage = this.handleGetObjectResponse;
|
||||
// Set up a global message listener for responses from the service worker.
|
||||
navigator.serviceWorker.addEventListener('message', async (event) => {
|
||||
console.log('Received message from service worker:', event.data);
|
||||
await this.handleServiceWorkerMessage(event.data);
|
||||
});
|
||||
|
||||
// Ensure the new service worker is activated before sending messages
|
||||
// Set up a periodic check to ensure the service worker is active and to send a SYNC message.
|
||||
this.serviceWorkerCheckIntervalId = window.setInterval(async () => {
|
||||
const activeWorker = this.serviceWorkerRegistration.active || (await this.waitForServiceWorkerActivation(this.serviceWorkerRegistration));
|
||||
|
||||
activeWorker?.postMessage(
|
||||
{ type: 'START' },
|
||||
[this.messageChannel.port2],
|
||||
);
|
||||
const service = await Services.getInstance();
|
||||
const payload = await service.getMyProcesses();
|
||||
activeWorker?.postMessage({ type: 'SCAN', payload });
|
||||
}, 5000);
|
||||
} catch (error) {
|
||||
console.error('Service Worker registration failed:', error);
|
||||
console.error('Service Worker registration failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,6 +187,46 @@ export class Database {
|
||||
}
|
||||
}
|
||||
|
||||
private async handleServiceWorkerMessage(message: any) {
|
||||
switch (message.type) {
|
||||
case 'TO_DOWNLOAD':
|
||||
console.log('Received data to download:', message.data);
|
||||
await this.handleDownloadList(message.data);
|
||||
break;
|
||||
default:
|
||||
console.warn('Unknown message type received from service worker:', message);
|
||||
}
|
||||
}
|
||||
|
||||
private async handleDownloadList(downloadList: string[]): void {
|
||||
// Download the missing data
|
||||
let requestedStateId = [];
|
||||
const service = await Services.getInstance();
|
||||
for (const hash of downloadList) {
|
||||
try {
|
||||
const valueBytes = await service.fetchValueFromStorage(hash);
|
||||
if (valueBytes) {
|
||||
// Save data to db
|
||||
const blob = new Blob([valueBytes], {type: "application/octet-stream"});
|
||||
await service.saveBlobToDb(hash, blob);
|
||||
} else {
|
||||
// We first request the data from managers
|
||||
console.log('Request data from managers of the process');
|
||||
// get the diff from db
|
||||
const diff = await service.getDiffByValue(hash);
|
||||
const processId = diff.process_id;
|
||||
const stateId = diff.state_id;
|
||||
if (!requestedStateId.includes(stateId)) {
|
||||
await service.requestDataFromPeers(processId, stateId);
|
||||
requestedStateId.push(stateId);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private handleAddObjectResponse = async (event: MessageEvent) => {
|
||||
const data = event.data;
|
||||
console.log('Received response from service worker (ADD_OBJECT):', data);
|
||||
@ -195,6 +234,7 @@ export class Database {
|
||||
if (data.type === 'NOTIFICATIONS') {
|
||||
service.setNotifications(data.data);
|
||||
} else if (data.type === 'TO_DOWNLOAD') {
|
||||
console.log(`Received missing data ${data}`);
|
||||
// Download the missing data
|
||||
let requestedStateId = [];
|
||||
for (const hash of data.data) {
|
||||
@ -220,8 +260,6 @@ export class Database {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
// try to update list of my processes
|
||||
await service.getMyProcesses();
|
||||
}
|
||||
};
|
||||
|
||||
@ -267,49 +305,6 @@ export class Database {
|
||||
});
|
||||
}
|
||||
|
||||
public updateMyProcesses(myProcessesId: string[]): Promise<void> {
|
||||
if (myProcessesId.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
if (!this.serviceWorkerRegistration) {
|
||||
// console.warn('Service worker registration is not ready. Waiting...');
|
||||
this.serviceWorkerRegistration = await navigator.serviceWorker.ready;
|
||||
}
|
||||
|
||||
const activeWorker = await this.waitForServiceWorkerActivation(this.serviceWorkerRegistration);
|
||||
// Create a message channel for communication
|
||||
const messageChannel = new MessageChannel();
|
||||
|
||||
// Handle the response from the service worker
|
||||
messageChannel.port1.onmessage = (event) => {
|
||||
if (event.data.status === 'success') {
|
||||
resolve();
|
||||
} else {
|
||||
const error = event.data.message;
|
||||
reject(new Error(error || 'Unknown error occurred while scanning our processes'));
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
const payload = { myProcessesId };
|
||||
console.log('Sending UPDATE_PROCESSES msg with payload', payload);
|
||||
activeWorker?.postMessage(
|
||||
{
|
||||
type: 'UPDATE_PROCESSES',
|
||||
|
||||
payload,
|
||||
},
|
||||
[messageChannel.port2],
|
||||
|
||||
);
|
||||
} catch (error) {
|
||||
reject(new Error(`Failed to send message to service worker: ${error}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async getObject(storeName: string, key: string): Promise<any | null> {
|
||||
const db = await this.getDb();
|
||||
const tx = db.transaction(storeName, 'readonly');
|
||||
|
Loading…
x
Reference in New Issue
Block a user