Attach looks at future observatory URIs#44637
Conversation
b7ef16e to
9bdf33e
Compare
jonahwilliams
left a comment
There was a problem hiding this comment.
Attach changes generally look good I think - though I would do more verification to ensure that we're cleaning exiting the loop on errors and cleaning up resources in between.
There was a problem hiding this comment.
What does changing this to a Stream do? I think It takes a list so that for -d all the runner can handle multiple vmservice addresses
There was a problem hiding this comment.
If I'm reading this correctly, it looks like as a list this has either 0 or 1 elements, so I don't think it's related to -d all. What I'm not sure about is why it had to be an empty list rather than null when there were no observatory uris.
There was a problem hiding this comment.
It appears the intention was to support multiple apps running an observatory on a single device, but it's not implemented. Was this done for Fuchsia?
There was a problem hiding this comment.
Yeah, it looks like this was for the now-deleted fuchsia_reload command. Fuchsia is now handled differently, so I think this can be safely modified.
There was a problem hiding this comment.
At any rate - I'm not really sure what modifying the resident runner here is accomplishing. Isn't the goal to adjust this behavior for attach only?
There was a problem hiding this comment.
As per offline discussion, I changed this such that it doesn't reuse the resident runner, which aligns with the expected lifecycle of the resident runner.
zanderso
left a comment
There was a problem hiding this comment.
Instead of making ProtocolDiscovery give a stream of Uris, did you consider having the attach command instead do a loop around _attachToDevice?
There was a problem hiding this comment.
If I'm reading this correctly, it looks like as a list this has either 0 or 1 elements, so I don't think it's related to -d all. What I'm not sure about is why it had to be an empty list rather than null when there were no observatory uris.
cfedba2 to
32bea4a
Compare
|
Capturing the offline conversation: The goal here is to discover the observatory URI of an app:
cc @zanderso |
|
Overall approach looks good. Need tests of reconnect, and follow-on PRs (or same PR, up to you) to support re-attaching with mdns (and other) discovery. |
349f855 to
42f6d74
Compare
|
This PR is ready for a final review. PTAL |
381046c to
e9dfe28
Compare
|
cc @devoncarew, @DanTup this should make the IDE specific work-around for Android flutter attach redundant. |
There was a problem hiding this comment.
This seems like a bug. We generally shouldn't be catching Error subclasses unless it is a temporary work around. If you are going to replace uri with uris I would do that in this PR
There was a problem hiding this comment.
I'm not sure I follow. If something called cancel too early, then this is the equivalent behavior in the current code.
There was a problem hiding this comment.
In what situation does _uriStreamController?.close() triggers the StateError? When you say uris.first after the _uriStreamController?.close()? Can you check _uriStreamController.isClosed or add an onCancel callback to _uriStreamController that records a bit?
There was a problem hiding this comment.
The situation is that there's a test returns non-null uri future under protocol_discovery_test.dart that expects uri to return a non-null value. For some reason, this works currently even though the uri future never completes. I checked the documentation for expect and it says:
" If [actual] is a [Future], the test won't complete until the future emits a value." However, it doesn't seem true in this case:
final Completer<void> _completer = Completer<Uri>();
expect(_completer.future, isNotNull);For this reason, the test is failing when migrated to streams. The stream is closed in the tearDown callback before a value is emitted.
There was a problem hiding this comment.
catching a StateError is definitely a bug. It implies there's some logic error in our code.
There was a problem hiding this comment.
Here and elsewhere, don't use broadcast streams. These do not buffer events, so if the future resolves before the first subscriber is added the event will be lost
There was a problem hiding this comment.
This seems to work fine:
import 'dart:async';
void main() async {
Stream<String> stream = Stream<String>.fromFuture(Future<String>.value('foo'))
.asBroadcastStream();
stream.listen((String value) {
print(value);
});
}
prints foo.
There was a problem hiding this comment.
The docs for asBroadcastStream() here:
The returned stream will subscribe to this stream when its first subscriber is added, and will stay subscribed until this stream ends, or a callback cancels the subscription.
In general though, I don't know if it would be needed to pass onListen and onCancel callbacks to asBroadcastStream() to pause and resume the underlying stream when the number of subscribers hits zero.
There was a problem hiding this comment.
It looks like you re-added the updates to resident runner. Were these changes necessary for some reason?
There was a problem hiding this comment.
yes -- observatoryUris is a stream instead of a list.
c2fa463 to
09cb892
Compare
e0bce47 to
e40ffe2
Compare
9dc4dd9 to
77bd8ec
Compare
|
(If LG to @zanderso ) |
| /// | ||
| /// Port forwarding is only attempted when this is invoked, | ||
| /// for each observatory URI in the stream. | ||
| Stream<Uri> get uris { |
There was a problem hiding this comment.
@blasten If you're changing this API's name anyhow, @Hixie has pointed out that there is no such thing as a URI, they're all URLs, so maybe this should be called urls instead?
| ) | ||
| ).asBroadcastStream(); | ||
| } | ||
| // If MDNS discovery fails or we're not on iOS, fallback to ProtocolDiscovery. |
There was a problem hiding this comment.
Sorry for not catching this earlier, but this fallback will no longer work since the Stream.fromFuture isn't going to return null. That is the null check below is no longer testing the success of the mdns lookup. Could you please do a small follow-up change that checks the return of MDnsObservatoryDiscovery.instance.getObservatoryUri() for null, and if it is null then uses ProtocolDiscovery.observatory() instead? Thanks!
There was a problem hiding this comment.
Sounds good. I will follow up on that!
Description
I refactored the the protocol discovery mechanism, so it looks at future observatory URIs instead of old ones. I'm sending this PR to get early feedback. I will then add unit tests.
The main change is that
observatoryUribecomes aStreamofUri.Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]). This will ensure a smooth and quick review process.///).flutter analyze --flutter-repo) does not report any problems on my PR.Breaking Change
Does your PR require Flutter developers to manually update their apps to accommodate your change?