[eas-cli] Pre-warm bsdiff patches against top-K base and embedded updates#3869
[eas-cli] Pre-warm bsdiff patches against top-K base and embedded updates#3869jc-expo wants to merge 5 commits into
Conversation
…ates Instead of only diffing against the second-most-recent update on the branch, issue HEAD requests for the top-K most recent updates and the registered embedded bundles, approximating the lazy path's organic base selection from real device traffic.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3869 +/- ##
==========================================
+ Coverage 58.45% 59.02% +0.58%
==========================================
Files 922 932 +10
Lines 40199 40794 +595
Branches 8462 8597 +135
==========================================
+ Hits 23493 24076 +583
- Misses 16610 16622 +12
Partials 96 96 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Have prewarmDiffingAsync return the list of successfully pre-warmed bsdiff patches so the top-K base + embedded-bundle selection can be asserted on, add tests for it, and route the prewarm HEAD through the ../fetch wrapper (proxy support + standard mocking).
Add minimal tests for the no-recent-updates, no-signed-url, and no-launch-asset cases to reach full patch coverage.
|
Subscribed to pull request
Generated by CodeMention |
| // registered embedded bundle. | ||
| const embeddedUpdateQuery = await EmbeddedUpdateQuery.viewPaginatedAsync(graphqlClient, { | ||
| appId, | ||
| filter: { platform, runtimeVersion: update.runtimeVersion }, |
There was a problem hiding this comment.
you'll need to also filter by channel to get the set of builds (with embedded updates) that are eligible to receive the published update
|
✅ Thank you for adding the changelog entry! |
| const channels = await ChannelQuery.viewUpdateChannelsBasicInfoPaginatedOnAppAsync( | ||
| graphqlClient, | ||
| { | ||
| appId, | ||
| first: PREWARM_CHANNELS_LIMIT, | ||
| } | ||
| ); | ||
| return channels.edges | ||
| .map(edge => edge.node) | ||
| .filter(channel => getBranchIds(getBranchMapping(channel.branchMapping)).includes(branchId)) | ||
| .map(channel => channel.name); | ||
| } |
There was a problem hiding this comment.
I forgot there's no graphql api for this yet. Can you open up a separate pr and add a channelPaginated edge off the UpdateBranch node to implement relay pagination like this:
const connection = await ChannelEntity.knexLoader(viewerContext, queryContext).loadPageAsync({
first,
after,
where: sql`filter_branch_id(${entityField('branchMapping')}) @>
${JSON.stringify(branch.getID())}::JSONB`,
pagination: {
strategy: PaginationStrategy.STANDARD,
orderBy: [{ fieldName: 'createdAt', order: OrderByOrdering.DESCENDING }],
},
});
Also if you could add a comment saying to only use this internally in the graphql api, that'd be great:
"""
INTERNAL USE ONLY. Channels whose branchMapping references this branch.
Branch -> channels is not a first-class relationship in EAS Update; do not
depend on this in public integrations.
"""
Why
Linear ENG-21079.
The previous
prewarmDiffingAsyncbase-update selection was too simple: it always pickedupdateIds[1]— the second-most-recent update on the branch (filtered byplatform + runtimeVersion). If the second-newest was a quick hotfix on top of the newest, most devices in the field are likely on the third newest (or older), so the pre-warmed bsdiff patch misses the base that real traffic actually requests.When a device requests a base that hasn't been pre-warmed, the server kicks off the diff on-demand but, until that patch is ready, serves the full un-diffed bundle. So a bad base guess means those clients download the entire update instead of a small patch until the diff finishes computing.
How
Pre-warm against the top-K candidates instead of a single base, approximating the bases that the lazy path organically catches from real device traffic:
prewarmUpdateDiffsAsync, kept it best-effort (failures are logged viaLog.debugand swallowed, never blocking a publish), and added debug logging throughout.Test Plan
yarn testfor theeas-clipackage passes.EXPO_DEBUG=1and confirmed the debug logs show the top-K recent updates and embedded bundles being queued and HEAD-requested with thea-im: bsdiffdiffing headers.