1
1
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2
2
// for details. All rights reserved. Use of this source code is governed by a
3
3
// BSD-style license that can be found in the LICENSE file.
4
-
5
4
import 'dart:async' ;
6
5
import 'dart:convert' ;
7
6
import 'dart:io' ;
@@ -17,6 +16,7 @@ import 'package:watcher/watcher.dart';
17
16
import 'package:web_socket_channel/web_socket_channel.dart' ;
18
17
19
18
import '../change_provider.dart' ;
19
+ import '../constants.dart' ;
20
20
import '../daemon_builder.dart' ;
21
21
import '../data/build_request.dart' ;
22
22
import '../data/build_target.dart' ;
@@ -31,24 +31,19 @@ import 'managers/build_target_manager.dart';
31
31
/// Note the server will only notify clients of pertinent events.
32
32
class Server {
33
33
static final loggerName = 'BuildDaemonServer' ;
34
-
35
- final _isDoneCompleter = Completer ();
34
+ final _isDoneCompleter = Completer <int >();
36
35
final BuildTargetManager _buildTargetManager;
37
36
final _pool = Pool (1 );
38
37
final Serializers _serializers;
39
38
final ChangeProvider _changeProvider;
40
39
late final Timer _timeout;
41
-
42
40
HttpServer ? _server;
43
41
final DaemonBuilder _builder;
44
42
// Channels that are interested in the current build.
45
43
var _interestedChannels = < WebSocketChannel > {};
46
-
47
44
final _subs = < StreamSubscription > [];
48
-
49
45
final _outputStreamController = StreamController <ServerLog >();
50
46
late final Stream <ServerLog > _logs;
51
-
52
47
Server (
53
48
this ._builder,
54
49
Duration timeout,
@@ -61,9 +56,7 @@ class Server {
61
56
BuildTargetManager (shouldBuildOverride: shouldBuild) {
62
57
_logs = _outputStreamController.stream;
63
58
_forwardData ();
64
-
65
59
_handleChanges (changeProvider.changes);
66
-
67
60
// Stop the server if nobody connects.
68
61
_timeout = Timer (timeout, () async {
69
62
if (_buildTargetManager.isEmpty) {
@@ -72,7 +65,8 @@ class Server {
72
65
});
73
66
}
74
67
75
- Future <void > get onDone => _isDoneCompleter.future;
68
+ /// Returns exit code.
69
+ Future <int > get onDone => _isDoneCompleter.future;
76
70
77
71
/// Starts listening for build daemon clients.
78
72
Future <int > listen () async {
@@ -98,7 +92,6 @@ class Server {
98
92
_removeChannel (channel);
99
93
});
100
94
});
101
-
102
95
var server = _server = await HttpMultiServer .loopback (0 );
103
96
// Serve requests in an error zone to prevent failures
104
97
// when running from another error zone.
@@ -124,7 +117,7 @@ class Server {
124
117
await sub.cancel ();
125
118
}
126
119
await _outputStreamController.close ();
127
- if (! _isDoneCompleter.isCompleted) _isDoneCompleter.complete ();
120
+ if (! _isDoneCompleter.isCompleted) _isDoneCompleter.complete (failureType );
128
121
}
129
122
130
123
Future <void > _build (
@@ -134,7 +127,6 @@ class Server {
134
127
buildTargets.expand (_buildTargetManager.channels).toSet ();
135
128
return _builder.build (buildTargets, changes);
136
129
});
137
-
138
130
void _forwardData () {
139
131
_subs
140
132
..add (_builder.logs.listen ((log) {
@@ -147,14 +139,11 @@ class Server {
147
139
// Don't serialize or send changed assets if the client isn't interested
148
140
// in them.
149
141
String ? message, messageWithoutChangedAssets;
150
-
151
142
for (var channel in _interestedChannels) {
152
143
var targets = _buildTargetManager.targetsFor (channel);
153
144
var wantsChangedAssets = targets
154
145
.any ((e) => e is DefaultBuildTarget && e.reportChangedAssets);
155
-
156
146
String messageForChannel;
157
-
158
147
if (wantsChangedAssets) {
159
148
messageForChannel =
160
149
message ?? = jsonEncode (_serializers.serialize (status));
@@ -163,7 +152,6 @@ class Server {
163
152
_serializers
164
153
.serialize (status.rebuild ((b) => b.changedAssets = null )));
165
154
}
166
-
167
155
channel.sink.add (messageForChannel);
168
156
}
169
157
}))
@@ -183,7 +171,15 @@ class Server {
183
171
var buildTargets = _buildTargetManager.targetsForChanges (changes);
184
172
if (buildTargets.isEmpty) return ;
185
173
await _build (buildTargets, changes);
186
- }).listen ((_) {}));
174
+ }).listen ((_) {}, onError: (e) {
175
+ stop (
176
+ message: 'Error in file change event: $e ' ,
177
+ failureType: fileChangeEventErrorCode);
178
+ }, onDone: () {
179
+ stop (
180
+ message: 'File change stream closed' ,
181
+ failureType: fileChangeStreamClosedErrorCode);
182
+ }));
187
183
}
188
184
189
185
void _removeChannel (WebSocketChannel channel) async {
0 commit comments