You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Property Editor] Property Editor is unresponsive after computer goes to sleep #9028
If you leave a project open in VS Code with the property editor open, it stops working when you come back to it the next day. I'm guessing it's because we've lost connection with the DTD, but will need to investigate more to confirm.
I think at the very least we should show a disconnected screen to the user with instructions on how to reconnect. Ideally we should automatically reconnect for them.
FYI @DanTup - I need to figure out if there is a way to reproduce that doesn't involve having to wait a few hours, but I wouldn't be surprised if this involves work in both DevTools and the VS Code extension. Will update here once I have more details.
Can you describe how it stops working? Are there exceptions? Are you no longer getting the events from the editor?
The Property Editor no longer responds to cursor position changes, and trying to trigger an edit results in an error.
There are some log files you can enable in your VS Code settings that might help
Ah that is helpful! I was able to re-trigger this with logs enabled (emailed you). As of yet, not seeing anything to indicate this is a VS Code extension issue.
Some notes so that I don't forget over the weekend:
This change along with exposing the following getter in DTD (described below) appear to keep the Property Editor alive.
I initially tried listening for DTD's done future (and reconnecting when done), however that did not work. Chrome puts the frame to sleep, and so the done future would be completed while the frame was asleep, and therefore we would never reconnect to DTD.
By pinging, even though the pings stop when Chrome puts the frame to sleep, when it is activated again, we begin pinging once more. When that happens, we can then handle reconnecting to DTD.
DTD changes:
Add the following getter:
/// Whether or not the connection is closed.
bool get isClosed => _clientPeer.isClosed;
However it doesn't seem to be accessible later. I wonder if adding a pingInterval parameter to WebSocket.connect would be reasonable?
I haven't tested this, but you could possibly patch DTD to inline some of those constructors so you have access to the raw dart:ioWebSocket to set pingInterval to see if it would help:
diff --git a/pkg/dtd/lib/src/dart_tooling_daemon.dart b/pkg/dtd/lib/src/dart_tooling_daemon.dart
index 57d6024d5a7..83e00d9da7f 100644
--- a/pkg/dtd/lib/src/dart_tooling_daemon.dart+++ b/pkg/dtd/lib/src/dart_tooling_daemon.dart@@ -4,10 +4,13 @@
import 'dart:async';
import 'dart:convert';
+import 'dart:io';
import 'package:json_rpc_2/json_rpc_2.dart';
import 'package:stream_channel/stream_channel.dart';
-import 'package:web_socket_channel/web_socket_channel.dart';+import 'package:web_socket/io_web_socket.dart' show IOWebSocket;+import 'package:web_socket_channel/adapter_web_socket_channel.dart'+ show AdapterWebSocketChannel;
import '../dtd.dart';
@@ -56,7 +59,11 @@ class DartToolingDaemon {
/// final client = DartToolingDaemon.connect(uri);
/// ```
static Future<DartToolingDaemon> connect(Uri uri) async {
- final channel = WebSocketChannel.connect(uri);+ final webSocket = await WebSocket.connect(uri.toString());+ webSocket.pingInterval = const Duration(minutes: 1); // We can set this here+ final ioSocket = IOWebSocket.fromWebSocket(webSocket);+ final channel = AdapterWebSocketChannel(ioSocket);+
await channel.ready;
return DartToolingDaemon.fromStreamChannel(channel.cast<String>());
}
diff --git a/pkg/dtd/pubspec.yaml b/pkg/dtd/pubspec.yaml
index 5c1775758d2..c6117e8c3f8 100644
--- a/pkg/dtd/pubspec.yaml+++ b/pkg/dtd/pubspec.yaml@@ -10,6 +10,7 @@ dependencies:
json_rpc_2: ^3.0.2
stream_channel: ^2.1.2
unified_analytics: ^7.0.0
+ web_socket:
web_socket_channel: '>=2.0.0 <4.0.0'
# We use 'any' version constraints here as we get our package versions from
Here from the DTD CL, just trying to get a clearer understanding of the problem. If the Future resolves in a sleeping tab, does that mean the program in the tab is still running? If so, shouldn't code to reconnect when the Future resolves still run in the tab too? Maybe the problem with that is networking is blocked in sleeping tabs. If so, can you set a dtdIsConnectionIsClosedbool when the Future resolves instead of checking dtd.isClosed?
If the Future resolves in a sleeping tab, does that mean the program in the tab is still running?
No, I don't think the program in the tab is still running. Chrome puts all processes in the tab to sleep - for example, I see that the pings I've added using Timer stop, and re-start again once the tab is re-awoken.
If so, shouldn't code to reconnect when the Future resolves still run in the tab too? Maybe the problem with that is networking is blocked in sleeping tabs. If so, can you set a dtdIsConnectionIsClosed bool when the Future resolves instead of checking dtd.isClosed?
I initially tried the following in DevTools (see below), however _attemptDtdReconnection never ended up getting called. However, when the tab was re-awoken, the DTD connection was closed. This is why I don't think waiting on the Future is sufficient here.
I think that _attemptDtdReconnection not getting called means that the Future never resolves. So I think the problem is that if package:json_rpc_2isn't running (e.g. is in a sleeping tab) when the disconnection happens, it never resolves the Future. There's probably a way to fix this, but adding dtd.isClosed to get around it works for me.
changed the title [-][Property Editor] Does not work when left overnight[/-][+][Property Editor] Property Editor is unresponsive after computer goes to sleep[/+]on Apr 2, 2025
Activity
elliette commentedon Mar 13, 2025
FYI @DanTup - I need to figure out if there is a way to reproduce that doesn't involve having to wait a few hours, but I wouldn't be surprised if this involves work in both DevTools and the VS Code extension. Will update here once I have more details.
DanTup commentedon Mar 13, 2025
Can you describe how it stops working? Are there exceptions? Are you no longer getting the events from the editor?
There are some log files you can enable in your VS Code settings that might help (for example if the issue is with DTD, there's a log for that):
elliette commentedon Mar 13, 2025
The Property Editor no longer responds to cursor position changes, and trying to trigger an edit results in an error.
Ah that is helpful! I was able to re-trigger this with logs enabled (emailed you). As of yet, not seeing anything to indicate this is a VS Code extension issue.
elliette commentedon Mar 14, 2025
Some notes so that I don't forget over the weekend:
This change along with exposing the following getter in DTD (described below) appear to keep the Property Editor alive.
I initially tried listening for
DTD'sdonefuture (and reconnecting whendone), however that did not work. Chrome puts the frame to sleep, and so thedonefuture would be completed while the frame was asleep, and therefore we would never reconnect to DTD.By pinging, even though the pings stop when Chrome puts the frame to sleep, when it is activated again, we begin pinging once more. When that happens, we can then handle reconnecting to DTD.
DTD changes:
Add the following getter:
elliette commentedon Mar 18, 2025
Unfortunately the solution described above works to keep the Property Editor alive for longer than before, but not enough to keep it alive overnight. After that, we get the following error when calling one of the APIs indicating that the websocket has closed: https://github.com/dart-lang/tools/blob/b55643dadafd3ac6b2bd20823802f75929ebf98e/pkgs/json_rpc_2/lib/src/client.dart#L151
Chatted with @DanTup offline, he suggested setting the
pingIntervalto try to keep the WebSocket alive: https://api.dart.dev/dart-io/WebSocket/pingInterval.htmlI believe this will require changes to package:json_rpc_2, but need investigate more here.
For now, my plan is:
isClosedgetter (described above)closedpingIntervalor some other mechanism to keep the websocket aliveDanTup commentedon Mar 20, 2025
I think the
WebSocketis available here:https://github.com/dart-lang/http/blob/1b6e28d7e1c61f7b0f8561be7aee9c35b03de193/pkgs/web_socket_channel/lib/src/channel.dart#L107-L108
However it doesn't seem to be accessible later. I wonder if adding a
pingIntervalparameter toWebSocket.connectwould be reasonable?I haven't tested this, but you could possibly patch DTD to inline some of those constructors so you have access to the raw
dart:ioWebSocketto setpingIntervalto see if it would help:derekxu16 commentedon Mar 20, 2025
Here from the DTD CL, just trying to get a clearer understanding of the problem. If the
Futureresolves in a sleeping tab, does that mean the program in the tab is still running? If so, shouldn't code to reconnect when theFutureresolves still run in the tab too? Maybe the problem with that is networking is blocked in sleeping tabs. If so, can you set adtdIsConnectionIsClosedboolwhen theFutureresolves instead of checkingdtd.isClosed?elliette commentedon Mar 20, 2025
No, I don't think the program in the tab is still running. Chrome puts all processes in the tab to sleep - for example, I see that the pings I've added using
Timerstop, and re-start again once the tab is re-awoken.I initially tried the following in DevTools (see below), however
_attemptDtdReconnectionnever ended up getting called. However, when the tab was re-awoken, the DTD connection was closed. This is why I don't think waiting on theFutureis sufficient here.derekxu16 commentedon Mar 20, 2025
I think that
_attemptDtdReconnectionnot getting called means that theFuturenever resolves. So I think the problem is that ifpackage:json_rpc_2isn't running (e.g. is in a sleeping tab) when the disconnection happens, it never resolves theFuture. There's probably a way to fix this, but addingdtd.isClosedto get around it works for me.Add isClosed method to DTD
[-][Property Editor] Does not work when left overnight[/-][+][Property Editor] Property Editor is unresponsive after computer goes to sleep[/+]