Skip to content

Commit ad7c645

Browse files
bkonyidart-scoped@luci-project-accounts.iam.gserviceaccount.com
authored andcommitted
[VM Service] Fix DevFS stream PUT requests
Resolves issues in DevFS handling where individual stream file PUT requests could result in flaky test failures on Windows. TAG=agy CONV=ae3a29f5-e2c8-499c-b221-ff61e40f5f1f Change-Id: I55d12cc55f35d1d1ed36742d442a3d4bebad53bf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505162 Reviewed-by: Nicholas Shahan <nshahan@google.com> Auto-Submit: Ben Konyi <bkonyi@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
1 parent 85da4df commit ad7c645

1 file changed

Lines changed: 22 additions & 14 deletions

File tree

pkg/dart_runtime_service_vm/lib/src/vm_dev_fs.dart

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@
55
import 'dart:async';
66
import 'dart:convert';
77
import 'dart:io';
8+
import 'dart:typed_data';
89

910
import 'package:dart_runtime_service/dart_runtime_service.dart';
1011
import 'package:file/local.dart';
1112

13+
Future<List<int>> _collectBytes(Stream<List<int>> stream) async {
14+
final builder = BytesBuilder(copy: false);
15+
await for (final chunk in stream) {
16+
builder.add(chunk);
17+
}
18+
return builder.takeBytes();
19+
}
20+
1221
/// An outstanding write request managed by [_WriteLimiter].
1322
class _PendingWrite {
1423
_PendingWrite({
@@ -20,7 +29,7 @@ class _PendingWrite {
2029

2130
final LocalFileSystem _localFs;
2231
final Uri uri;
23-
final Stream<List<int>> bytes;
32+
final List<int> bytes;
2433

2534
Future<void> write() async {
2635
final file = _localFs.file(uri);
@@ -29,9 +38,7 @@ class _PendingWrite {
2938
if (await file.exists()) {
3039
await file.delete();
3140
}
32-
final sink = file.openWrite();
33-
await sink.addStream(bytes);
34-
await sink.close();
41+
await file.writeAsBytes(bytes, flush: true);
3542
completer.complete();
3643
_WriteLimiter._writeCompleted();
3744
}
@@ -51,19 +58,20 @@ abstract class _WriteLimiter {
5158
required LocalFileSystem localFs,
5259
required Uri uri,
5360
required List<int> bytes,
54-
}) => scheduleWriteStream(
55-
localFs: localFs,
56-
uri: uri,
57-
bytes: Stream.fromIterable([bytes]),
58-
);
61+
}) {
62+
final pw = _PendingWrite(localFs: localFs, uri: uri, bytes: bytes);
63+
pendingWrites.add(pw);
64+
_maybeWriteFiles();
65+
return pw.completer.future;
66+
}
5967

6068
static Future<void> scheduleWriteStream({
6169
required LocalFileSystem localFs,
6270
required Uri uri,
6371
required Stream<List<int>> bytes,
64-
}) {
65-
// Create a new pending write.
66-
final pw = _PendingWrite(localFs: localFs, uri: uri, bytes: bytes);
72+
}) async {
73+
final collectedBytes = await _collectBytes(bytes);
74+
final pw = _PendingWrite(localFs: localFs, uri: uri, bytes: collectedBytes);
6775
pendingWrites.add(pw);
6876
_maybeWriteFiles();
6977
return pw.completer.future;
@@ -150,7 +158,7 @@ final class VMDevelopmentFileSystem extends DevelopmentFileSystem {
150158
@override
151159
Future<RpcResponse> listFiles() async {
152160
final dir = _localFs.directory(rootUri);
153-
final dirPathStr = dir.path;
161+
final dirPathStr = Uri.file(dir.path).path;
154162
final stream = dir.list(recursive: true);
155163
final files = <Map<String, Object?>>[];
156164
await for (final fileEntity in stream) {
@@ -160,7 +168,7 @@ final class VMDevelopmentFileSystem extends DevelopmentFileSystem {
160168
filePath.startsWith(dirPathStr)) {
161169
files.add(<String, Object?>{
162170
// Remove any url-encoding in the filenames.
163-
'name': Uri.decodeFull('/${filePath.substring(dirPathStr.length)}'),
171+
'name': Uri.decodeFull(filePath.substring(dirPathStr.length)),
164172
'size': stat.size,
165173
'modified': stat.modified.millisecondsSinceEpoch,
166174
});

0 commit comments

Comments
 (0)