
ARGUMENT SUMMATION: Give a clear and concise statement as to why I should invest money in this project.
Washington Irving, "The Legend of Sleepy Hollow", Rip Van Winkle"
Nathaniel Hawthorne, The Scarlet Letter, "Young Goodman Brown", My Kinsman, Major Molineux.
Herman Melville, "Bartleby", Moby-Dick, "Benito Cereno"
Edgar Allen Poe, "The Fall of the House of Usher", "The Cask of Amontilado", The Masque of Red Death, "The Tell Tale Heart", "The Man of the Crowd".<issue_start><issue_comment>Title: Added timeout for closing devfs sync http connections.
username_0: ## Description

HttpClientRequest.close is randomly hanging then throwing a generic exception after 4 minutes.  I've filed a bug against dart and introduced a timeout in flutter since the request that would fail to converge on close would succeed on the second attempt in my testing.

I was able to validate with local testing that this addresses the issue and the 500ms timeout is well above my observed time for close to succeed which was more like 10ms in my observations.

## Related Issues

https://github.com/flutter/flutter/issues/63869

## Tests

I added the following tests:

none

## 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.

- [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
- [x] I signed the [CLA].
- [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
- [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.
- [x] The analyzer (`flutter analyze --flutter-repo`) does not report any problems on my PR.
- [x] I am willing to follow-up on review comments in a timely manner.

## Breaking Change

Did any tests fail when you ran them? Please read [Handling breaking changes].

- [x] No, no existing tests failed, so this is *not* a breaking change.
- [ ] Yes, this is a breaking change. *If not, delete the remainder of this section.*
   - [ ] I wrote a design doc: https://flutter.dev/go/template *Replace this with a link to your design doc's short link*
   - [ ] I got input from the developer relations team, specifically from: *Replace with the names of who gave advice*
   - [ ] I wrote a migration guide: https://flutter.dev/go/breaking-changes-template *Replace this with a link to a pull request that adds the migration guide to https://flutter.dev/docs/release/breaking-changes*

<!-- Links -->
[issue database]: https://github.com/flutter/flutter/issues
[Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Test Coverage]: https://github.com/flutter/flutter/wiki/Test-coverage-for-package%3Aflutter
[Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[Features we expect every widget to implement]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[Handling breaking changes]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
<issue_comment>username_1: Were you ever able to repro? I'd rather know what changed between 1.17 and 1.20 and track down the bug, rather than just timing out.  @username_2 was investigating this area with https://github.com/flutter/flutter/pull/54123.  There was also a lot of asset work done this release. @username_3 @dnfield
<issue_comment>username_2: Ah, that PR was something else.

As for this PR, 4 minutes sounds like an OS-level connection timeout. We might be able to bring that in by setting `connectionTimeout` on the `HttpClient`. Of course, that won't help if the client is already connected, and is timing out afterwards.

However, client request output is buffered (buffer size 8KB): https://api.dart.dev/dev/2.10.0-146.0.dev/dart-io/HttpClientRequest/bufferOutput.html, so we might not be trying to connect and send anything until the `close()` call.

If we think the transfer is taking too long, we should use `abort()` https://api.dart.dev/dev/2.10.0-146.0.dev/dart-io/HttpClientRequest/abort.html after the timeout to clean up the connection properly instead of leaking it for 4 minutes.

As @username_1 says however, it would be nice to find the root cause before adding the timeout, but adding the timeout is not terrible here since we've already got a retry loop.
<issue_comment>username_3: Should we be using platform specific tools in order to upload binaries/assets to each device instead of HTTP? Once we have the devFS location presumably we could use something like `adb push`/`ios-deploy something`. Is that more reliable?
<issue_comment>username_3: Wrote up go/flutter-improving-devfs-reliability to discuss some options
<issue_comment>username_3: In general I think playing with the timeouts here is a bit scary. We don't really know how long it should take to sync an asset
<issue_comment>username_0: @username_1 @username_3 @username_2   Yes, I was able to reproduce it.  The bug is in closing the http request.  It is a bug in the Dart http library.  I've filed an issue.

We already have timeouts for this call.  They are 4 minutes long which is dictated by Dart.  This timeout is one that is more amenable to our users and is 50x the observed duration during normal operation.  Closing the request happens after the data has already been sent, so we do know how long it should take.  The call before close is the one that scales based on the size of the payload.

Regardless, the devfs sync operation retries 10 times, so even if it somehow prematurely times out, it would have to exhibit the pathological case 9 more times and prematurely timeout 9 times which is highly unlikely.
<issue_comment>username_0: One other thing to consider is that even if Dart fixes the http code, we will still want an apropos timeout.
<issue_comment>username_0: It's also possible that the bug is in the devfs server.  Do we own that code?  I'm thinking it might possibly be closing a connection when it receives the payload before returning a status code, that would match my observations.
<issue_comment>username_3: Yes, the devFS is part of the dart vm service: https://github.com/dart-lang/sdk/blob/master/sdk/lib/vmservice/devfs.dart
<issue_comment>username_3: there are a few associated files there, but do note that we use the HTTP API and not the JSON-RPC API
<issue_comment>username_3: I agree that fixing this may involve changing/adding timeouts, but given that we don't really seem to know the cause I'm a bit concerned that we'd just be sort of papering-over some other issue. If you can reproduce the syncing issues fairly consistently it seems like the best course of action would be to identify the actual error condition we're hitting on the device/devFS
<issue_comment>username_1: I was never able to get it to repro.  I can help bisecting if I can figure out how to do so.
<issue_comment>username_1: Just to link it here, @username_3 opened https://github.com/flutter/flutter/pull/66266
<issue_comment>username_0: That's usually how internet protocols work, that's why there is the "Robustness principle" that dictates that we be liberal with what we accept.  That means we need to consider the fact that the server, now and in the future, may not return a status code to our PUT request.
<issue_comment>username_3: We control both the client and the