[O] Fix a race condition in vmservice_test.dart#23529
Conversation
|
cc @zanderso |
|
/cc @aam |
There was a problem hiding this comment.
Curious: is there a reason why i++ is less desirable?
There was a problem hiding this comment.
in this case, not really. In the general case, ++ suffix can be less efficient (since it has to store the value, then increment it, then use it), so ++ prefix is preferred. But that's ugly. So I pre-emptively turn ++ into the equivalent += 1 to make people more comfortable with += 1 so that the issue of ++ prefix can go away. :-)
There was a problem hiding this comment.
Does it matter in this case?
There was a problem hiding this comment.
Should/can this be List<Object> too, since you change dynamic to Object below?
There was a problem hiding this comment.
I think the JSON logic creates List<dynamic>s, not List<Object>s.
There was a problem hiding this comment.
=> invokeRpcRaw('getVM');
There was a problem hiding this comment.
I think my intent was not to await here, so refreshViews could continue without blocking. Was there a reason you put await back?
There was a problem hiding this comment.
The caller of refreshViews() can choose to not await the returned future. The use of async/await here is semantically equivalent to what you were trying to do with the Completer.
There was a problem hiding this comment.
yeah these are identical semantically. I happened to have already made this change on my branch; I didn't put the await back so much as have to resolve the merge, and I went with the shorter option. :-)
There was a problem hiding this comment.
Similarly, can we avoid awaiting in this method and instead let caller await if it decided it needed to?
There was a problem hiding this comment.
The return value of this method will be a future that will complete when all the futures have completed. It's still up to the caller to await the future returned by this method or not.
There was a problem hiding this comment.
await future; ...rest of method... is exactly equivalent to return future.then(...rest of method...).
There was a problem hiding this comment.
Add a comment explaining that upon completion of this RPC, _viewCache will be updated.
There was a problem hiding this comment.
Can listViews ever legitimately turn up no FlutterView instances? If so, we'll retry here until we eventually fail, even though there was no failure...
There was a problem hiding this comment.
Though I guess that's what waitForViews is for (why why it defaults to false)?
There was a problem hiding this comment.
I don't know the answer to your first question, but if so, I don't know how we would distinguish that case from the normal case where we don't want to return until we have a view.
The argument defaults to false so as to not change the default behaviour in the regular case; only in the specific case where I believe we definitely need a view did I set it to true.
|
thanks for the reviews, will land on green |
|
Reverting this since it broke a test. cc @aam we might want to work together on this... both of our patches in the same area had the same problem. |
|
Specifically, named_isolates_test failed. |
| for (FlutterDevice device in flutterDevices) | ||
| await device.refreshViews(); | ||
| futures.add(device.refreshViews()); | ||
| await Future.wait(futures); |
There was a problem hiding this comment.
This is the change that breaks named_isolates_test.
From what I can tell flutter engine is getting stuck processing two concurrent listViews requests https://github.com/flutter/engine/blob/master/runtime/service_protocol.cc#L237.
There was a problem hiding this comment.
To reproduce the failure pick up this new implementation of refreshViews() method and run named_isolates_test locally from $FH/flutter/dev/devicelab: $FH/flutter/bin/cache/dart-sdk/bin/dart bin/run.dart -t named_isolates_test
There was a problem hiding this comment.
I am fixing refreshViews so it is app-wide, rather than isolate-specific message, that should fix deadlock in the engine((in 89665ac). @chinmaygarde is making engine more robust to these kind of scenarios.
* Revert "[H] Created a variant of InheritedWidget specifically for Listenables (flutter#23393)" This reverts commit 9313285. * Revert "Fix a race condition in vmservice_test.dart (flutter#23529)" This reverts commit 5e7b0a3.
Fixes #19273