Skip to content

Commit

Permalink
fix: SQLite Busy - Locked (#6918)
Browse files Browse the repository at this point in the history
* fix:  increase the connection pool size to allow more concurrent connections to the SQLite database.

* fix: remove .then() and use async/await

* fix: remove .then() and use async/await

* fix: use transaction instead of workaround/trick

* fix: remove unnecessary console.log(...)

* fix: set max pool to 1 for sqlite3 database
  • Loading branch information
adkif authored Oct 2, 2023
1 parent 3ba05cd commit 1f1024c
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 138 deletions.
132 changes: 64 additions & 68 deletions apps/desktop-timer/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,90 +74,88 @@ export class AppComponent implements OnInit, AfterViewInit {

ngAfterViewInit(): void {
this.electronService.ipcRenderer.on('collect_data', (event, arg) =>
this._ngZone.run(() => {
this.appService
.collectEvents(arg.tpURL, arg.tp, arg.start, arg.end)
.then((res) => {
event.sender.send('data_push_activity', {
timerId: arg.timerId,
windowEvent: res,
type: 'APP',
});
});
this._ngZone.run(async () => {
const res = await this.appService.collectEvents(
arg.tpURL,
arg.tp,
arg.start,
arg.end
);
event.sender.send('data_push_activity', {
timerId: arg.timerId,
windowEvent: res,
type: 'APP',
});
})
);

this.electronService.ipcRenderer.on('collect_afk', (event, arg) =>
this._ngZone.run(() => {
this.appService
.collectAfk(arg.tpURL, arg.tp, arg.start, arg.end)
.then((res) => {
event.sender.send('data_push_activity', {
timerId: arg.timerId,
windowEvent: res,
type: 'AFK',
});
});
this._ngZone.run(async () => {
const res = await this.appService.collectAfk(
arg.tpURL,
arg.tp,
arg.start,
arg.end
);
event.sender.send('data_push_activity', {
timerId: arg.timerId,
windowEvent: res,
type: 'AFK',
});
})
);

this.electronService.ipcRenderer.on(
'collect_chrome_activities',
(event, arg) =>
this._ngZone.run(() => {
this.appService
.collectChromeActivityFromAW(
this._ngZone.run(async () => {
const res =
await this.appService.collectChromeActivityFromAW(
arg.tpURL,
arg.start,
arg.end
)
.then((res) => {
event.sender.send('data_push_activity', {
timerId: arg.timerId,
windowEvent: res,
type: 'URL',
});
});
);
event.sender.send('data_push_activity', {
timerId: arg.timerId,
windowEvent: res,
type: 'URL',
});
})
);

this.electronService.ipcRenderer.on(
'collect_firefox_activities',
(event, arg) =>
this._ngZone.run(() => {
this.appService
.collectFirefoxActivityFromAw(
this._ngZone.run(async () => {
const res =
await this.appService.collectFirefoxActivityFromAw(
arg.tpURL,
arg.start,
arg.end
)
.then((res) => {
event.sender.send('data_push_activity', {
timerId: arg.timerId,
windowEvent: res,
type: 'URL',
});
});
);
event.sender.send('data_push_activity', {
timerId: arg.timerId,
windowEvent: res,
type: 'URL',
});
})
);

this.electronService.ipcRenderer.on('server_ping', (event, arg) =>
this._ngZone.run(() => {
const pingHost = setInterval(() => {
this.appService
.pingServer(arg)
.then((res) => {
console.log('Server Found');
const pingHost = setInterval(async () => {
try {
await this.appService.pingServer(arg);
console.log('Server Found');
event.sender.send('server_is_ready');
clearInterval(pingHost);
} catch (error) {
console.log('ping status result', error.status);
if (this.store.userId) {
event.sender.send('server_is_ready');
clearInterval(pingHost);
})
.catch((e) => {
console.log('ping status result', e.status);
if (this.store.userId) {
event.sender.send('server_is_ready');
clearInterval(pingHost);
}
});
}
}
}, 1000);
})
);
Expand All @@ -166,21 +164,19 @@ export class AppComponent implements OnInit, AfterViewInit {
'server_ping_restart',
(event, arg) =>
this._ngZone.run(() => {
const pingHost = setInterval(() => {
this.appService
.pingServer(arg)
.then((res) => {
console.log('server found');
const pingHost = setInterval(async() => {
try {
await this.appService.pingServer(arg);
console.log('Server Found');
event.sender.send('server_already_start');
clearInterval(pingHost);
} catch (error) {
console.log('ping status result', error.status);
if (this.store.userId) {
event.sender.send('server_already_start');
clearInterval(pingHost);
})
.catch((e) => {
console.log('ping status result', e.status);
if (this.store.userId) {
event.sender.send('server_already_start');
clearInterval(pingHost);
}
});
}
}
}, 3000);
})
);
Expand Down
86 changes: 31 additions & 55 deletions packages/desktop-libs/src/lib/desktop-timer-activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,19 @@ export const TimerData = {
await timerService.update(timer);
},
insertWindowEvent: async (knex: Knex, query, retry = 0) => {
try {
await knex('window-events')
.insert(query)
.onConflict('eventId')
.merge(['duration', 'data', 'updated_at', 'type']);
} catch (error) {
if (
error.message
.toLowerCase()
.indexOf(
'Knex: Timeout acquiring a connection'.toLowerCase()
) > -1
) {
if (retry < 3) {
await TimerData.wait(3000);
return await TimerData.insertWindowEvent(
knex,
query,
retry + 1
);
}
await knex.transaction(async (trx: Knex.Transaction) => {
try {
await trx('window-events')
.insert(query)
.onConflict('eventId')
.merge(['duration', 'data', 'updated_at', 'type']);
await trx.commit();
} catch (error) {
await trx.rollback();
console.log('error on insert window-events', error);
throw error;
}
console.log('error on insert window-events', error);
throw error;
}
});
},
updateWindowEventUpload: async (knex, data) => {
return await knex('window-events')
Expand Down Expand Up @@ -81,38 +69,26 @@ export const TimerData = {
});
},
insertAfkEvent: async (knex: Knex, query, retry = 0) => {
try {
await knex('afk-events')
.insert(query)
.onConflict('eventId')
.merge([
'duration',
'timerId',
'data',
'updated_at',
'timeSlotId',
'timeSheetId'
]);
} catch (error) {
if (
error.message
.toLowerCase()
.indexOf(
'Knex: Timeout acquiring a connection'.toLowerCase()
) > -1
) {
if (retry < 3) {
await TimerData.wait(3000);
return await TimerData.insertAfkEvent(
knex,
query,
retry + 1
);
}
await knex.transaction(async (trx: Knex.Transaction) => {
try {
await knex('afk-events')
.insert(query)
.onConflict('eventId')
.merge([
'duration',
'timerId',
'data',
'updated_at',
'timeSlotId',
'timeSheetId',
]);
await trx.commit();
} catch (error) {
await trx.rollback();
console.log('error on insert afk-events', error);
throw error;
}
console.log('error on insert afk-events', error);
throw error;
}
});
},
getLastTimer: async (knex, appInfo) => {
return await timerService.findLastOne();
Expand Down
31 changes: 18 additions & 13 deletions packages/desktop-libs/src/lib/desktop-wakatime.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
export const metaData = {
getActivity: (knex, date) => {
return knex
.select('*')
.from('heartbeats')
.whereBetween('time', [date.end, date.start])
.then((res) => res)
.catch((error) => console.log(error));
getActivity: async (knex, date) => {
try {
return await knex
.select('*')
.from('heartbeats')
.whereBetween('time', [date.end, date.start]);
} catch (error) {
console.error(error);
}
},
removeActivity: (knex, data) => {
return knex('heartbeats')
.whereIn('id', data.idsWakatime)
.del()
.then((res) => res)
.catch((error) => console.log(error));

removeActivity: async (knex, data) => {
try {
return await knex('heartbeats')
.whereIn('id', data.idsWakatime)
.del();
} catch (error) {
console.error(error);
}
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export class SqliteProvider implements IServerLessProvider {
timezone: 'utc'
},
pool: {
min: 2,
max: 5,
min: 0,
max: 1,
createTimeoutMillis: 3000,
acquireTimeoutMillis: 60 * 1000 * 2,
idleTimeoutMillis: 30000,
Expand Down

0 comments on commit 1f1024c

Please sign in to comment.