Skip to content

Commit ab72ccc

Browse files
committed
check and resuse active app state for each appId
1 parent 1e99bf0 commit ab72ccc

File tree

1 file changed

+33
-35
lines changed

1 file changed

+33
-35
lines changed

webdev/lib/src/daemon/app_domain.dart

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ class AppDomain extends Domain {
2525

2626
final _appStates = <String, _AppState>{};
2727

28-
// Prevents duplicate stdout listeners for the same appId
29-
final _activeListeners = <String>{};
30-
3128
// Mapping from service name to service method.
3229
final Map<String, String> _registeredMethodsForService = <String, String>{};
3330

@@ -66,30 +63,30 @@ class AppDomain extends Domain {
6663

6764
Future<void> _handleAppConnections(WebDevServer server) async {
6865
final dwds = server.dwds!;
66+
6967
// The connection is established right before `main()` is called.
7068
await for (final appConnection in dwds.connectedApps) {
69+
final appId = appConnection.request.appId;
70+
71+
// Check if we already have an active app state for this appId
72+
if (_appStates.containsKey(appId)) {
73+
// Reuse existing connection, just run main again
74+
appConnection.runMain();
75+
continue;
76+
}
77+
7178
final debugConnection = await dwds.debugConnection(appConnection);
7279
final debugUri = debugConnection.ddsUri ?? debugConnection.uri;
7380
final vmService = await vmServiceConnectUri(debugUri);
74-
final appId = appConnection.request.appId;
75-
unawaited(debugConnection.onDone.then((_) {
76-
sendEvent('app.log', {
77-
'appId': appId,
78-
'log': 'Lost connection to device.',
79-
});
80-
sendEvent('app.stop', {
81-
'appId': appId,
82-
});
83-
daemon.shutdown();
84-
}));
81+
8582
sendEvent('app.start', {
8683
'appId': appId,
8784
'directory': Directory.current.path,
8885
'deviceId': 'chrome',
8986
'launchMode': 'run'
9087
});
9188

92-
// Set up VM service listeners (only once per appId to prevent duplicates)
89+
// Set up VM service listeners for this appId
9390
// ignore: cancel_subscriptions
9491
final stdOutSub = await _setupVmServiceListeners(appId, vmService);
9592

@@ -110,7 +107,18 @@ class AppDomain extends Domain {
110107

111108
appConnection.runMain();
112109

113-
unawaited(debugConnection.onDone.whenComplete(() {
110+
// Handle connection termination - send events first, then cleanup
111+
unawaited(debugConnection.onDone.then((_) {
112+
sendEvent('app.log', {
113+
'appId': appId,
114+
'log': 'Lost connection to device.',
115+
});
116+
sendEvent('app.stop', {
117+
'appId': appId,
118+
});
119+
daemon.shutdown();
120+
121+
// Clean up app resources
114122
_cleanupAppConnection(appId, appState);
115123
}));
116124
}
@@ -212,27 +220,19 @@ class AppDomain extends Domain {
212220
return true;
213221
}
214222

215-
/// Sets up VM service listeners for the given appId if not already active.
216-
/// Returns the stdout subscription if created, null otherwise.
217-
Future<StreamSubscription<Event>?> _setupVmServiceListeners(
223+
/// Sets up VM service listeners for the given appId.
224+
/// Returns the stdout subscription.
225+
Future<StreamSubscription<Event>> _setupVmServiceListeners(
218226
String appId, VmService vmService) async {
219-
if (_activeListeners.contains(appId)) {
220-
return null; // Already listening for this appId
221-
}
222-
223-
_activeListeners.add(appId);
224-
225-
// TODO(grouma) - limit the catch to the appropriate error.
226227
try {
227-
await vmService.streamCancel('Stdout');
228+
vmService.onServiceEvent.listen(_onServiceEvent);
229+
await vmService.streamListen('Service');
228230
} catch (_) {}
231+
232+
// Set up stdout listener
229233
try {
230234
await vmService.streamListen('Stdout');
231235
} catch (_) {}
232-
try {
233-
vmService.onServiceEvent.listen(_onServiceEvent);
234-
await vmService.streamListen('Service');
235-
} catch (_) {}
236236

237237
// ignore: cancel_subscriptions
238238
return vmService.onStdoutEvent.listen((log) {
@@ -247,7 +247,6 @@ class AppDomain extends Domain {
247247
void _cleanupAppConnection(String appId, _AppState appState) {
248248
appState.dispose();
249249
_appStates.remove(appId);
250-
_activeListeners.remove(appId);
251250
}
252251

253252
@override
@@ -257,14 +256,13 @@ class AppDomain extends Domain {
257256
state.dispose();
258257
}
259258
_appStates.clear();
260-
_activeListeners.clear();
261259
}
262260
}
263261

264262
class _AppState {
265263
final DebugConnection _debugConnection;
266264
final StreamSubscription<BuildResult> _resultSub;
267-
final StreamSubscription<Event>? _stdOutSub;
265+
final StreamSubscription<Event> _stdOutSub;
268266

269267
bool _isDisposed = false;
270268

@@ -275,7 +273,7 @@ class _AppState {
275273
void dispose() {
276274
if (_isDisposed) return;
277275
_isDisposed = true;
278-
_stdOutSub?.cancel();
276+
_stdOutSub.cancel();
279277
_resultSub.cancel();
280278
_debugConnection.close();
281279
}

0 commit comments

Comments
 (0)