Skip to content
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

Prefetch snapshot so as to avoid network call from critical path. #5968

Merged
merged 18 commits into from
May 3, 2021

Conversation

jatgarg
Copy link
Contributor

@jatgarg jatgarg commented Apr 27, 2021

Fixes: #5171
This adds an api to fetch the latest snapshot and store it the persisted cache. Hosts can then use it to prefetch before loading the container so as to avoid the trees/latest network call from critical path as then the snapshot will be fetched from the cache.

@jatgarg jatgarg added api area: driver Driver related issues labels Apr 27, 2021
@jatgarg jatgarg added this to the April 2021 milestone Apr 27, 2021
@jatgarg jatgarg self-assigned this Apr 27, 2021
@jatgarg
Copy link
Contributor Author

jatgarg commented Apr 27, 2021

Still need to add tests. Just creating a PR so that people can take a look and give suggestions.

@christiango
Copy link
Member

Do we have an easy way to see the bundle size of just importing the prefetch API on the host side? I know FF has some issues with tree shaking in a few places

@jatgarg
Copy link
Contributor Author

jatgarg commented Apr 27, 2021

Do we have an easy way to see the bundle size of just importing the prefetch API on the host side? I know FF has some issues with tree shaking in a few places

The bundle size change will get mentioned in this PR once the build completes.

@github-actions github-actions bot requested a review from vladsud April 27, 2021 21:40
@christiango
Copy link
Member

Do we have an easy way to see the bundle size of just importing the prefetch API on the host side? I know FF has some issues with tree shaking in a few places

The bundle size change will get mentioned in this PR once the build completes.

It will get added for existing code paths, but I'm curious the bundle size of just consuming the new API. I would recommend reaching out to @heliocliu to see the best way to hook up this new API to bundle analysis

@vladsud
Copy link
Contributor

vladsud commented Apr 27, 2021

Can we incorporate this new flow into packages\test\test-service-load somehow? Or maybe (in addition to it?) add to one of the examples / web loader? I.e. something that we can use to manually hit this path, as we have no test coverage at all and it's just a matter of time till we break it (or do not find that it does not work as is)

@github-actions github-actions bot requested a review from vladsud April 27, 2021 23:48
import { PerformanceEvent } from "@fluidframework/telemetry-utils";
import { IOdspSnapshot } from "./contracts";

export function evalBlobsAndTrees(snapshot: IOdspSnapshot) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than an odspUtils2.ts, what about just creating two separate files: evalBlobsAndTrees.ts and toInstrementedOdspTokenFetcher.ts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I added these to odsputils only because we already import a lot from that file. So no need to add these in a separate file.

@jatgarg
Copy link
Contributor Author

jatgarg commented Apr 28, 2021

@christiango I added the api in bundle size analysis after discussing with @heliocliu. The increase is just 2.12 KB.

@github-actions github-actions bot requested a review from vladsud April 28, 2021 22:12
@microsoft microsoft deleted a comment from msfluid-bot Apr 28, 2021
Copy link
Contributor

@vladsud vladsud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need test coverage. It's fine for it to have it as separate PR (as you are planning to add it to webpack loader), but please test it end-to-end with that flow before merging

@github-actions github-actions bot requested a review from vladsud April 29, 2021 17:58
@anthony-murphy
Copy link
Contributor

■ @fluidframework/base-host: No change
⯅ @fluid-example/bundle-size-tests: +31.34 KB
Metric Name Baseline Size Compare Size Size Diff
container.js 205.58 KB 205.59 KB ⯅ +11 Bytes
map.js 49.66 KB 49.67 KB ⯅ +4 Bytes
matrix.js 144.28 KB 144.29 KB ⯅ +8 Bytes
odspDriver.js 212.49 KB 214.52 KB ⯅ +2.03 KB
sharedString.js 159.14 KB 159.15 KB ⯅ +9 Bytes
Total Size 771.16 KB 802.5 KB ⯅ +31.34 KB
Baseline commit: 16c8ac1

Generated by 🚫 dangerJS against a94c097

@heliocliu total size looks wrong, its looks be counting bytes as KB.

Also, @christiango we stamp bundle size changes on the PR, but need successfull build

@christiango
Copy link
Member

■ @fluidframework/base-host: No change
⯅ @fluid-example/bundle-size-tests: +31.34 KB
Metric Name Baseline Size Compare Size Size Diff
container.js 205.58 KB 205.59 KB ⯅ +11 Bytes
map.js 49.66 KB 49.67 KB ⯅ +4 Bytes
matrix.js 144.28 KB 144.29 KB ⯅ +8 Bytes
odspDriver.js 212.49 KB 214.52 KB ⯅ +2.03 KB
sharedString.js 159.14 KB 159.15 KB ⯅ +9 Bytes
Total Size 771.16 KB 802.5 KB ⯅ +31.34 KB
Baseline commit: 16c8ac1
Generated by 🚫 dangerJS against a94c097

@heliocliu total size looks wrong, its looks be counting bytes as KB.

Also, @christiango we stamp bundle size changes on the PR, but need successful build

The total size seems correct to me, it's presumably the sum of all other entrypoints + any dynamic imports. Yeah, I'm guessing we just don't represent newly added bundles since we don't have a basline to compare against. But given the total size change it seems like this preload API will be a ~30KB hit to the bundle. @Zlatkovsky - might be worth reaching out to teams folks to see if this 30KB hit would be problematic for the functionality we want to add.

@microsoft microsoft deleted a comment from msfluid-bot Apr 29, 2021
@@ -127,6 +128,9 @@ export interface OdspFluidDataStoreLocator extends IOdspUrlParts {
fileVersion?: string;
}

// @public
export function prefetchLatestSnapshot(resolvedUrl: IResolvedUrl, getStorageToken: TokenFetcher<OdspResourceTokenFetchOptions>, persistedCache: IPersistedCache, logger: ITelemetryBaseLogger, hostSnapshotFetchOptions: ISnapshotOptions | undefined): Promise<boolean>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vladsud is this the right package for this? should this be dynamically loaded? are there versioning implication for this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine for now. Basically only driver factory and driver factory input/output times (that are all defined in odsp-driver-definitions) are subject for dynamic loading.
Long term yes, we should separate driver (implementation) into multiple packages, and likely move out error handling code out of odsp-doclib-utils package into its own package.

The tests also validate only that factory is compatible with old versions of loader / runtime (merged this morning).

@microsoft microsoft deleted a comment from msfluid-bot Apr 30, 2021
@msfluid-bot
Copy link
Collaborator

msfluid-bot commented Apr 30, 2021

@fluidframework/base-host: No change
Metric NameBaseline SizeCompare SizeSize Diff
main.js 175.49 KB 175.49 KB No change
Total Size 175.49 KB 175.49 KB No change
@fluid-example/bundle-size-tests: +25.39 KB
Metric NameBaseline SizeCompare SizeSize Diff
container.js 205.58 KB 205.59 KB +11 Bytes
map.js 49.66 KB 49.67 KB +4 Bytes
matrix.js 144.28 KB 144.29 KB +8 Bytes
odspDriver.js 210.96 KB 213.01 KB +2.05 KB
sharedString.js 159.14 KB 159.15 KB +9 Bytes
Total Size 769.63 KB 795.02 KB +25.39 KB

Baseline commit: 3f262e4

Generated by 🚫 dangerJS against 2df4150


export function apisToBundle() {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
prefetchLatestSnapshot(undefined as any, undefined as any, undefined as any, undefined as any, undefined);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emails suggested that this produced 30kb bundle. Is this really the case? There is not much code in here.
It's worth taking a look on why it's so large. I assume numbers are for non-minimized code, right?

Copy link
Member

@christiango christiango Apr 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be minified code. I would recommend having someone take a look of the output of a plugin like this when we run just this api through webpack in production mode: https://github.com/webpack-contrib/webpack-bundle-analyzer

Copy link
Contributor Author

@jatgarg jatgarg Apr 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prefetchSnapshot api file seems to be about ~10Kb and then almost all utilities are used from odspUtils which also seems to account for ~10KB and then there are some other imports from driver-defn, assert, uuid etc which could have accounted for 10Kb more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heliocliu These are non-minimized bundle size, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metric is for minified code. The 30kb includes all its dependencies (and their dependencies, etc) as well. If a host were to take a dependency on this method without already having any dependencies on this method's dependencies, the host would incur a 30kb size increase. Like mentioned before, the tool doesn't seem to handle new metrics well, but the way it produces the numbers in the table is otherwise simple and the difference in the Total Size Size Diff value and the sum of individual Size Diff values gives the size of the newly added metrics

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replied in the email with division of sizes. Just pasting here but we can continue discussion in email thread.

Source Size(KB)
OdspPrefetchSnapshot(Main code file) 2.72
Common-utils 3.86
uuid 1.14
node-fetch 0.325
ms/index.js 1.38
node_modules/debug/src 4.26
Telemetry utils 5.05
odsp-doclib-utils 3.5
driver-utils 4.16
Driver-defn 2.07
  28.465

@jatgarg jatgarg merged commit d16cb73 into microsoft:main May 3, 2021
@jatgarg jatgarg deleted the prefetch branch May 3, 2021 20:43
@tylerbutler tylerbutler added area: examples Changes that focus on our examples breaking change This PR or issue would introduce a breaking change labels May 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api area: driver Driver related issues area: examples Changes that focus on our examples breaking change This PR or issue would introduce a breaking change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add API to ODSP driver for "prefetching" snapshots in to persistent cache
9 participants