Skip to content
This repository has been archived by the owner on Jun 4, 2023. It is now read-only.

Commit

Permalink
fix: history saving race conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
sentialx committed Apr 2, 2020
1 parent dff54e2 commit d43df0a
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 29 deletions.
1 change: 1 addition & 0 deletions src/main/services/storage.ts
Expand Up @@ -17,6 +17,7 @@ import {
import { countVisitedTimes } from '~/utils/history';
import { windowsManager } from '..';
import { promises } from 'fs';
import { Queue } from '~/utils/queue';

interface Databases {
[key: string]: Datastore;
Expand Down
68 changes: 39 additions & 29 deletions src/main/view.ts
Expand Up @@ -13,6 +13,7 @@ import {
ZOOM_FACTOR_INCREMENT,
} from '~/constants/web-contents';
import { TabEvent } from '~/interfaces/tabs';
import { Queue } from '~/utils/queue';

export class View extends BrowserView {
public title = '';
Expand All @@ -32,6 +33,8 @@ export class View extends BrowserView {

public bookmark: IBookmark;

private historyQueue = new Queue();

public constructor(window: AppWindow, url: string, incognito: boolean) {
super({
webPreferences: {
Expand Down Expand Up @@ -273,18 +276,22 @@ export class View extends BrowserView {
date: new Date().getTime(),
};

this.lastHistoryId = (
await storage.insert<IHistoryItem>({
scope: 'history',
item: historyItem,
})
)._id;
await this.historyQueue.enqueue(async () => {
this.lastHistoryId = (
await storage.insert<IHistoryItem>({
scope: 'history',
item: historyItem,
})
)._id;

historyItem._id = this.lastHistoryId;
historyItem._id = this.lastHistoryId;

storage.history.push(historyItem);
storage.history.push(historyItem);
});
} else if (!inPage) {
this.lastHistoryId = '';
await this.historyQueue.enqueue(async () => {
this.lastHistoryId = '';
});
}
}

Expand All @@ -311,29 +318,32 @@ export class View extends BrowserView {

public async updateData() {
if (!this.incognito) {
if (this.lastHistoryId) {
const id = this.lastHistoryId;
if (id) {
const { title, url, favicon } = this;

storage.update({
scope: 'history',
query: {
_id: this.lastHistoryId,
},
value: {
title,
url,
favicon,
},
multi: false,
this.historyQueue.enqueue(async () => {
await storage.update({
scope: 'history',
query: {
_id: id,
},
value: {
title,
url,
favicon,
},
multi: false,
});

const item = storage.history.find(x => x._id === id);

if (item) {
item.title = title;
item.url = url;
item.favicon = favicon;
}
});

const item = storage.history.find(x => x._id === this.lastHistoryId);

if (item) {
item.title = title;
item.url = url;
item.favicon = favicon;
}
}
}
}
Expand Down
50 changes: 50 additions & 0 deletions src/utils/queue.ts
@@ -0,0 +1,50 @@
export class Queue {
private queue: {
promise: () => Promise<any>;
reject: any;
resolve: any;
}[] = [];
private pendingPromise = false;

public enqueue<T>(promise: () => Promise<T>): Promise<T> {
return new Promise((resolve, reject) => {
this.queue.push({
promise,
resolve,
reject,
});

this.dequeue();
});
}

public dequeue() {
if (this.pendingPromise) {
return false;
}
const item = this.queue.shift();
if (!item) {
return false;
}
try {
this.pendingPromise = true;
item
.promise()
.then(value => {
this.pendingPromise = false;
item.resolve(value);
this.dequeue();
})
.catch(err => {
this.pendingPromise = false;
item.reject(err);
this.dequeue();
});
} catch (err) {
this.pendingPromise = false;
item.reject(err);
this.dequeue();
}
return true;
}
}

0 comments on commit d43df0a

Please sign in to comment.