Refactor stream inteceptor

Summary:
There was a frustrating issue previously where the UI would jump everytime a new frame came in with bloks data. This would occur constantly as the client was generating new frames every 10 seconds. The issue was because the previous appraoch to speed up the augmentation was to display the raw client raw and then asynchronously process a new frame with the added derived components.

The issue was the raw client frame has less nodes so we would breifly display this, and because the reduciton trace was cache on the next tick we would show this causing a jump.

Now we have a new solution:

1. We use an event emitter to push frames / metadata into the interceptor
2. The interceptor should always produce 1 frame, this can be the same or augmented, for open source its just the same
3. We use react query to check if we already have the reduction trace cached, if so then we are able to quickly process the whole thing, if not its split into 2 parts.

React query is also nice since we can add a cache time for the reduciton traces which are very large and not useful one your screen is gone. This should help keep memory usage under control a bit.

one other benefit to this approach is i can remove the error handling stuff from the main plugin code, since the blok augmentation is not on the critical path and it can retry internally and push out a new frame whenever.

Reviewed By: antonk52

Differential Revision: D49272152

fbshipit-source-id: e5539d36231a32754e8612014195449b9faafdb1
This commit is contained in:
Luke De Feo
2023-09-15 04:05:43 -07:00
committed by Facebook GitHub Bot
parent bc5ad749f7
commit 21b4423231
5 changed files with 99 additions and 144 deletions

View File

@@ -8,25 +8,21 @@
*/
import {DeviceOS} from 'flipper-plugin';
import {Id, Metadata, ClientNode} from '../ClientTypes';
import {StreamInterceptor} from '../DesktopTypes';
import {StreamInterceptorEventEmitter} from '../DesktopTypes';
export function getStreamInterceptor(_: DeviceOS): StreamInterceptor {
return new NoOpStreamInterceptor();
}
class NoOpStreamInterceptor implements StreamInterceptor {
init() {
return null;
}
async transformNodes(
nodes: Map<Id, ClientNode>,
): Promise<[Map<Id, ClientNode>, Metadata[]]> {
return [nodes, []];
}
async transformMetadata(metadata: Metadata): Promise<Metadata> {
return metadata;
}
/**
* Stream inteceptors have the change to modify the frame or metata early in the pipeline
*/
export function addInterceptors(
_deviceOS: DeviceOS,
eventEmitter: StreamInterceptorEventEmitter,
) {
//no-op impmentation for open source
eventEmitter.on('frameReceived', async (frame) => {
eventEmitter.emit('frameUpdated', frame);
});
eventEmitter.on('metadataReceived', async (metadata) => {
eventEmitter.emit('metadataUpdated', metadata);
});
}