Skip to content

Commit 36bb024

Browse files
controller inactivity issue fixed (#20)
1 parent e21a05a commit 36bb024

File tree

4 files changed

+50
-3
lines changed

4 files changed

+50
-3
lines changed

packages/controller-ext/manifest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"tabGroups",
1515
"webNavigation",
1616
"downloads",
17-
"browserOS"
17+
"browserOS",
18+
"alarms"
1819
],
1920
"host_permissions": [
2021
"<all_urls>"

packages/controller-ext/src/background/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import type { ProtocolRequest, ProtocolResponse} from '@/protocol/types';
3737
import { ConnectionStatus } from '@/protocol/types';
3838
import { ConcurrencyLimiter } from '@/utils/ConcurrencyLimiter';
3939
import { getWebSocketPort } from '@/utils/ConfigHelper';
40+
import { KeepAlive } from '@/utils/KeepAlive';
4041
import { logger } from '@/utils/Logger';
4142
import { RequestTracker } from '@/utils/RequestTracker';
4243
import { RequestValidator } from '@/utils/RequestValidator';
@@ -302,6 +303,8 @@ chrome.runtime.onInstalled.addListener(() => {
302303
chrome.runtime.onStartup.addListener(async () => {
303304
logger.info('[BrowserOS Controller] Browser started');
304305

306+
await KeepAlive.start();
307+
305308
if (!controller) {
306309
const port = await getWebSocketPort();
307310
controller = new BrowserOSController(port);
@@ -311,6 +314,9 @@ chrome.runtime.onStartup.addListener(async () => {
311314

312315
// Start immediately (service worker context)
313316
(async () => {
317+
// Start KeepAlive to prevent service worker from being terminated
318+
await KeepAlive.start();
319+
314320
if (!controller) {
315321
const port = await getWebSocketPort();
316322
controller = new BrowserOSController(port);
@@ -326,12 +332,13 @@ chrome.runtime.onStartup.addListener(async () => {
326332
})();
327333

328334
// Cleanup on unload
329-
chrome.runtime.onSuspend?.addListener(() => {
335+
chrome.runtime.onSuspend?.addListener(async () => {
330336
logger.info('[BrowserOS Controller] Extension suspending');
331337
if (controller) {
332338
controller.stop();
333339
controller = null;
334340
}
341+
await KeepAlive.stop();
335342
});
336343

337344
// Export for debugging in console

packages/controller-ext/src/config/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export const WEBSOCKET_CONFIG: WebSocketConfig = {
4444
reconnectMultiplier: 1.5,
4545
maxReconnectAttempts: Infinity,
4646

47-
heartbeatInterval: 30000,
47+
heartbeatInterval: 20000,
4848
heartbeatTimeout: 5000,
4949

5050
connectionTimeout: 10000,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @license
3+
* Copyright 2025 BrowserOS
4+
* SPDX-License-Identifier: AGPL-3.0-or-later
5+
*/
6+
import { logger } from '@/utils/Logger';
7+
8+
const KEEPALIVE_ALARM_NAME = 'browseros-keepalive';
9+
const KEEPALIVE_INTERVAL_MINUTES = 0.33; // ~20 seconds
10+
11+
export class KeepAlive {
12+
private static isInitialized = false;
13+
14+
static async start(): Promise<void> {
15+
if (this.isInitialized) {
16+
logger.debug('KeepAlive already started');
17+
return;
18+
}
19+
20+
chrome.alarms.onAlarm.addListener((alarm) => {
21+
if (alarm.name === KEEPALIVE_ALARM_NAME) {
22+
logger.debug('KeepAlive: ping (service worker alive)');
23+
}
24+
});
25+
26+
await chrome.alarms.create(KEEPALIVE_ALARM_NAME, {
27+
periodInMinutes: KEEPALIVE_INTERVAL_MINUTES,
28+
});
29+
30+
this.isInitialized = true;
31+
logger.info(`KeepAlive started: alarm every ${KEEPALIVE_INTERVAL_MINUTES * 60}s`);
32+
}
33+
34+
static async stop(): Promise<void> {
35+
await chrome.alarms.clear(KEEPALIVE_ALARM_NAME);
36+
this.isInitialized = false;
37+
logger.info('KeepAlive stopped');
38+
}
39+
}

0 commit comments

Comments
 (0)