Skip to content

Commit cd80335

Browse files
authored
Merge branch 'master' into feat/lints-4-0
2 parents 30d68f2 + a97c2a1 commit cd80335

File tree

4 files changed

+101
-17
lines changed

4 files changed

+101
-17
lines changed

dwds/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
- Fix bug where debugging clients are not aware of service extensions when connecting to a new web app. - [#2388](https://github.com/dart-lang/webdev/pull/2388)
44
- Respect the value of `pause_isolates_on_start` during page-refreshes. - [#2431](https://github.com/dart-lang/webdev/pull/2431)
5+
- Fix issue where DAP clients wouldn't resume after a restart. - [#2441](https://github.com/dart-lang/webdev/pull/2441)
6+
- Add implementation for the VM Service's `getFlagList` API. - [#2438](https://github.com/dart-lang/webdev/pull/2438)
57

68
## 24.0.0
79

dwds/lib/src/dwds_vm_client.dart

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef VmResponse = Map<String, Object?>;
2828

2929
enum _NamespacedServiceExtension {
3030
extDwdsEmitEvent(method: 'ext.dwds.emitEvent'),
31+
extDwdsReload(method: 'ext.dwds.reload'),
3132
extDwdsRestart(method: 'ext.dwds.restart'),
3233
extDwdsScreenshot(method: 'ext.dwds.screenshot'),
3334
extDwdsSendEvent(method: 'ext.dwds.sendEvent'),
@@ -77,6 +78,8 @@ class DwdsVmClient {
7778
final requestSink = requestController.sink;
7879
final requestStream = requestController.stream;
7980

81+
final clientCompleter = Completer<VmService>();
82+
8083
_setUpVmServerConnection(
8184
chromeProxyService: chromeProxyService,
8285
debugService: debugService,
@@ -85,6 +88,7 @@ class DwdsVmClient {
8588
requestStream: requestStream,
8689
requestSink: requestSink,
8790
dwdsStats: dwdsStats,
91+
clientFuture: clientCompleter.future,
8892
);
8993

9094
final client = ddsUri == null
@@ -97,6 +101,10 @@ class DwdsVmClient {
97101
ddsUri: ddsUri,
98102
);
99103

104+
if (!clientCompleter.isCompleted) {
105+
clientCompleter.complete(client);
106+
}
107+
100108
final dwdsVmClient =
101109
DwdsVmClient(client, requestController, responseController);
102110

@@ -158,12 +166,14 @@ class DwdsVmClient {
158166
required StreamSink<VmResponse> responseSink,
159167
required Stream<VmRequest> requestStream,
160168
required StreamSink<VmRequest> requestSink,
169+
required Future<VmService> clientFuture,
161170
}) {
162171
responseStream.listen((request) async {
163172
final response = await _maybeHandleServiceExtensionRequest(
164173
request,
165174
chromeProxyService: chromeProxyService,
166175
dwdsStats: dwdsStats,
176+
clientFuture: clientFuture,
167177
);
168178
if (response != null) {
169179
requestSink.add(response);
@@ -187,15 +197,19 @@ class DwdsVmClient {
187197
VmResponse request, {
188198
required ChromeProxyService chromeProxyService,
189199
required DwdsStats dwdsStats,
200+
required Future<VmService> clientFuture,
190201
}) async {
191202
VmRequest? response;
192203
final method = request['method'];
193204
if (method == _NamespacedServiceExtension.flutterListViews.method) {
194205
response = await _flutterListViewsHandler(chromeProxyService);
195206
} else if (method == _NamespacedServiceExtension.extDwdsEmitEvent.method) {
196207
response = _extDwdsEmitEventHandler(request);
208+
} else if (method == _NamespacedServiceExtension.extDwdsReload.method) {
209+
response = await _extDwdsReloadHandler(chromeProxyService);
197210
} else if (method == _NamespacedServiceExtension.extDwdsRestart.method) {
198-
response = await _extDwdsRestartHandler(chromeProxyService);
211+
final client = await clientFuture;
212+
response = await _extDwdsRestartHandler(chromeProxyService, client);
199213
} else if (method == _NamespacedServiceExtension.extDwdsSendEvent.method) {
200214
response = await _extDwdsSendEventHandler(request, dwdsStats);
201215
} else if (method == _NamespacedServiceExtension.extDwdsScreenshot.method) {
@@ -265,13 +279,21 @@ class DwdsVmClient {
265279
return {'result': Success().toJson()};
266280
}
267281

268-
static Future<Map<String, Object>> _extDwdsRestartHandler(
282+
static Future<Map<String, Object>> _extDwdsReloadHandler(
269283
ChromeProxyService chromeProxyService,
270284
) async {
271285
await _fullReload(chromeProxyService);
272286
return {'result': Success().toJson()};
273287
}
274288

289+
static Future<Map<String, Object>> _extDwdsRestartHandler(
290+
ChromeProxyService chromeProxyService,
291+
VmService client,
292+
) async {
293+
await _hotRestart(chromeProxyService, client);
294+
return {'result': Success().toJson()};
295+
}
296+
275297
static Future<void> _registerServiceExtensions({
276298
required VmService client,
277299
required ChromeProxyService chromeProxyService,

dwds/lib/src/services/chrome_proxy_service.dart

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,20 @@ class ChromeProxyService implements VmServiceInterface {
9292

9393
StreamSubscription<ConsoleAPIEvent>? _consoleSubscription;
9494

95-
bool _pauseIsolatesOnStart = false;
95+
/// The flags that can be set at runtime via [setFlag] and their respective
96+
/// values.
97+
final Map<String, bool> _currentVmServiceFlags = {
98+
_pauseIsolatesOnStartFlag: false,
99+
};
96100

97101
/// The value of the [_pauseIsolatesOnStartFlag].
98102
///
99103
/// This value can be updated at runtime via [setFlag].
100-
bool get pauseIsolatesOnStart => _pauseIsolatesOnStart;
104+
bool get pauseIsolatesOnStart =>
105+
_currentVmServiceFlags[_pauseIsolatesOnStartFlag] ?? false;
106+
107+
/// Whether or not the connected app has a pending restart.
108+
bool get hasPendingRestart => _resumeAfterRestartEventsController.hasListener;
101109

102110
final _resumeAfterRestartEventsController =
103111
StreamController<String>.broadcast();
@@ -353,6 +361,20 @@ class ChromeProxyService implements VmServiceInterface {
353361
);
354362
}
355363

364+
// If the new isolate was created as part of a restart, send a
365+
// kPausePostRequest event to notify client that the app is paused so that
366+
// it can resume:
367+
if (hasPendingRestart) {
368+
_streamNotify(
369+
'Debug',
370+
Event(
371+
kind: EventKind.kPausePostRequest,
372+
timestamp: timestamp,
373+
isolate: isolateRef,
374+
),
375+
);
376+
}
377+
356378
// The service is considered initialized when the first isolate is created.
357379
if (!_initializedCompleter.isCompleted) _initializedCompleter.complete();
358380
}
@@ -758,9 +780,22 @@ ${globalToolConfiguration.loadStrategy.loadModuleSnippet}("dart_sdk").developer.
758780
}
759781

760782
@override
761-
Future<FlagList> getFlagList() async {
762-
// VM flags do not apply to web apps.
763-
return FlagList(flags: []);
783+
Future<FlagList> getFlagList() {
784+
return wrapInErrorHandlerAsync(
785+
'getFlagList',
786+
_getFlagList,
787+
);
788+
}
789+
790+
Future<FlagList> _getFlagList() {
791+
final flags = _currentVmServiceFlags.entries.map<Flag>(
792+
(entry) => Flag(
793+
name: entry.key,
794+
valueAsString: '${entry.value}',
795+
),
796+
);
797+
798+
return Future.value(FlagList(flags: flags.toList()));
764799
}
765800

766801
@override
@@ -1214,14 +1249,12 @@ ${globalToolConfiguration.loadStrategy.loadModuleSnippet}("dart_sdk").developer.
12141249
);
12151250

12161251
Future<Success> _setFlag(String name, String value) async {
1217-
if (!_supportedVmServiceFlags.contains(name)) {
1252+
if (!_currentVmServiceFlags.containsKey(name)) {
12181253
return _rpcNotSupportedFuture('setFlag');
12191254
}
12201255

1221-
if (name == _pauseIsolatesOnStartFlag) {
1222-
assert(value == 'true' || value == 'false');
1223-
_pauseIsolatesOnStart = value == 'true';
1224-
}
1256+
assert(value == 'true' || value == 'false');
1257+
_currentVmServiceFlags[name] = value == 'true';
12251258

12261259
return Success();
12271260
}
@@ -1699,8 +1732,3 @@ const _stderrTypes = ['error'];
16991732
const _stdoutTypes = ['log', 'info', 'warning'];
17001733

17011734
const _pauseIsolatesOnStartFlag = 'pause_isolates_on_start';
1702-
1703-
/// The flags that can be set at runtime via [setFlag].
1704-
const _supportedVmServiceFlags = {
1705-
_pauseIsolatesOnStartFlag,
1706-
};

dwds/test/chrome_proxy_service_test.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,6 +2099,38 @@ void main() {
20992099
});
21002100
});
21012101

2102+
group('getFlagList', () {
2103+
List<String> stringifyFlags(FlagList flagList) {
2104+
return flagList.flags
2105+
?.map((flag) => '${flag.name} -> ${flag.valueAsString}')
2106+
.toList() ??
2107+
[];
2108+
}
2109+
2110+
test('returns expected default values', () async {
2111+
final service = context.service;
2112+
final flagList = await service.getFlagList();
2113+
expect(
2114+
stringifyFlags(flagList),
2115+
containsAll([
2116+
'pause_isolates_on_start -> false',
2117+
]),
2118+
);
2119+
});
2120+
2121+
test('returns any modified flag values', () async {
2122+
final service = context.service;
2123+
await service.setFlag('pause_isolates_on_start', 'true');
2124+
final flagList = await service.getFlagList();
2125+
expect(
2126+
stringifyFlags(flagList),
2127+
containsAll([
2128+
'pause_isolates_on_start -> true',
2129+
]),
2130+
);
2131+
});
2132+
});
2133+
21022134
group('streamListen/onEvent', () {
21032135
late ChromeProxyService service;
21042136

0 commit comments

Comments
 (0)