Cache the results of getVersion and getIsolate#3309
Cache the results of getVersion and getIsolate#3309elliette merged 13 commits intoflutter:masterfrom
getVersion and getIsolate#3309Conversation
getVersion and getIsolatesgetVersion and getIsolate
| @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.
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.
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.
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.
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?
| _connectionAvailableController.add(service); | ||
|
|
||
| // Clear the isolates cache: | ||
| isolateManager.clearIsolateIdCache(); |
There was a problem hiding this comment.
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
registerIsolatewith the cached isolate - when the isolate changes,
onMainIsolateChangedis called, which callsregisterIsolatewith the new isolate
|
|
||
| final ValueListenable<IsolateRef> _mainIsolate; | ||
|
|
||
| final IsolateF _getIsolateCached; |
There was a problem hiding this comment.
why not just use the serviceManager isolate cache directly instead of passing in this function?
There was a problem hiding this comment.
Now using the pre existing cache :)
| ValueListenable<IsolateRef> get mainIsolate => _mainIsolate; | ||
| final _mainIsolate = ValueNotifier<IsolateRef>(null); | ||
|
|
||
| final _isolatesCache = <String, Isolate>{}; |
There was a problem hiding this comment.
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.
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.
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.
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.
call this _registerMainIsolate for clarity.
| await _registerIsolate(isolate, isolateRef); | ||
| } | ||
|
|
||
| Future<void> _registerIsolate(Isolate isolate, |
There was a problem hiding this comment.
parameter name should not be previousIsolateRef. It should be expectedMainIsolateRef or similar.

Reduces the number of calls we make to
getVersionandgetIsolatein order to help improvement initial page load time.Previously we were calling both multiple times:
After this change, we call
getVersiononly once, andgetIsolatetwice. The secondgetIsolatecall comes from thedebugger_controller.