-
Notifications
You must be signed in to change notification settings - Fork 340
Cache the results of getVersion
and getIsolate
#3309
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
getVersion
and getIsolates
getVersion
and getIsolate
@@ -370,8 +371,9 @@ class VmServiceWrapper implements VmService { | |||
} | |||
|
|||
@override | |||
Future<Isolate> getIsolate(String isolateId) { | |||
return trackFuture('getIsolate', _vmService.getIsolate(isolateId)); | |||
Future<Isolate> getIsolate(String isolateId) async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use the cache in the IsolateManager everywhere possible rather than making this API cached as I think there are legitimate times we would need to get a new Isolate object. Just using the cache for all the cases on the startup path should be sufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm interesting! It looks like getIsolate
is only being called once from the IsolateManager
on startup. The other calls on start-up are coming from the ServiceExtensionManager
and the DebuggerController
. One option perhaps is to cache the values just for the duration of the vmServiceOpened
method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah feel free to flow the value through vmServiceOpened so none of the calls within it repeat fetching the isolate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'm caching the value in IsolateManager
and using it in vmServiceOpened
(then clearing that value at the end of vmServiceOpened
). However, it's possible I still might be overly caching - for example, as part of vmServiceOpened
, the _onMainIsolateChanged
method gets called, and I'm using the cached value there: https://github.com/flutter/devtools/blob/master/packages/devtools_app/lib/src/service_manager.dart#L914. Wdyt?
@@ -315,6 +317,9 @@ class ServiceConnectionManager { | |||
} | |||
|
|||
_connectionAvailableController.add(service); | |||
|
|||
// Clear the isolates cache: | |||
isolateManager.clearIsolateIdCache(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was mostly worried about clearing the cached isolate value because it was being used in onMainIsolateChanged
(which was called on start up). I've now split out the registration logic from onMainIsolateChanged
(because that seems to be why we were calling it on start up, to register the isolate). So now:
- on start up, we call
registerIsolate
with the cached isolate - when the isolate changes,
onMainIsolateChanged
is called, which callsregisterIsolate
with the new isolate
|
||
VmServiceWrapper _service; | ||
|
||
bool _checkForFirstFrameStarted = false; | ||
|
||
final ValueListenable<IsolateRef> _mainIsolate; | ||
|
||
final IsolateF _getIsolateCached; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just use the serviceManager isolate cache directly instead of passing in this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now using the pre existing cache :)
@@ -542,6 +547,8 @@ class IsolateManager extends Disposer { | |||
ValueListenable<IsolateRef> get mainIsolate => _mainIsolate; | |||
final _mainIsolate = ValueNotifier<IsolateRef>(null); | |||
|
|||
final _isolatesCache = <String, Isolate>{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is already an isolateCache. Use it directly for cases where a cache is suitable rather than creating another one. I believe it is in IsolateManager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the existing cache is being used to cache the isolate states, not the isolate itself. It never actually sends a request for the isolate[1], which we need to do. Though I don't understand how the existing cache is getting the isolate without requesting it explicitly, so I might be mistaken!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realized why the pre-existing cache wasn't working is because I was using it in _loadIsolateState
. Now we are using the cache everywhere except loadIsolateState
, which is where we make the request for the isolate.
} | ||
|
||
Future<void> _registerIsolate(Isolate isolate, | ||
[IsolateRef previousIsolateRef]) async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in general avoid optional positional parameters. they just lead to bugs when they are sometimes used and sometimes not used. In general prefer optional named parameters as they provide more clarity about the intent of the parameters for cases where optional parameters are needed. not sure if this is in the style guide but is implicitly the case for flutter.
final isolateRef = _isolateManager.mainIsolate.value; | ||
final Isolate isolate = await _isolateManager.getIsolateCached(isolateRef); | ||
|
||
await _registerIsolate(isolate, isolateRef); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
call this _registerMainIsolate for clarity.
await _registerIsolate(isolate, isolateRef); | ||
} | ||
|
||
Future<void> _registerIsolate(Isolate isolate, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parameter name should not be previousIsolateRef. It should be expectedMainIsolateRef or similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reduces the number of calls we make to
getVersion
andgetIsolate
in order to help improvement initial page load time.Previously we were calling both multiple times:
After this change, we call
getVersion
only once, andgetIsolate
twice. The secondgetIsolate
call comes from thedebugger_controller
.