-
-
Notifications
You must be signed in to change notification settings - Fork 130
fix: serve /data success rate from global_stats #2706
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2587,15 +2587,18 @@ export async function getPluginBreakdownCF(c: Context, referenceDate?: Date): Pr | |
|
|
||
| const PUBLIC_FAILURE_ACTIONS = ['set_fail', 'update_fail', 'download_fail', 'windows_path_fail', 'canonical_path_fail', 'directory_path_fail', 'unzip_fail', 'low_mem_fail', 'download_manifest_file_fail', 'download_manifest_checksum_fail', 'download_manifest_brotli_fail', 'finish_download_fail', 'manifest_path_fail', 'decrypt_fail', 'insufficient_disk_space', 'cannotGetBundle', 'checksum_fail', 'blocked_by_server_url', 'backend_refusal'] as const | ||
|
|
||
| export interface PublicLiveUpdateMetrics { | ||
| success_rate: number | ||
| daily: Array<{ date: string, success_rate: number }> | ||
| export interface PublicLiveUpdateBreakdownMetrics { | ||
| failures: Array<{ reason: string, share: number }> | ||
| platforms: { ios: number, android: number, electron: number } | ||
| updater_versions: Array<{ date: string, version: string, share: number }> | ||
| } | ||
|
|
||
| export async function getPublicLiveUpdateMetricsCF(c: Context, referenceDate = new Date()): Promise<PublicLiveUpdateMetrics> { | ||
| export type PublicLiveUpdateMetrics = PublicLiveUpdateBreakdownMetrics & { | ||
| success_rate: number | ||
| daily: Array<{ date: string, success_rate: number }> | ||
| } | ||
|
|
||
| export async function getPublicLiveUpdateMetricsCF(c: Context, referenceDate = new Date()): Promise<PublicLiveUpdateBreakdownMetrics> { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: Callers can reasonably expect Prompt for AI agents |
||
| if (!c.env.APP_LOG || !c.env.DEVICE_USAGE || !c.env.DEVICE_INFO || !getEnv(c, 'CF_ANALYTICS_TOKEN') || !getEnv(c, 'CF_ACCOUNT_ANALYTICS_ID')) | ||
| throw new Error('Public live update metric bindings are unavailable') | ||
|
|
||
|
|
@@ -2605,28 +2608,16 @@ export async function getPublicLiveUpdateMetricsCF(c: Context, referenceDate = n | |
| const window = `timestamp >= toDateTime('${formatDateCF(start)}') AND timestamp < toDateTime('${formatDateCF(end)}')` | ||
| const failureActions = PUBLIC_FAILURE_ACTIONS.map(action => `'${action}'`).join(', ') | ||
| const day = `formatDateTime(toStartOfInterval(timestamp, INTERVAL '1' DAY), '%Y-%m-%d')` | ||
| const outcomesQuery = `SELECT date, sum(succeeded) AS successes, sum(if(succeeded = 0, failed, 0)) AS failures FROM (SELECT ${day} AS date, index1 AS app_id, blob1 AS device_id, max(if(blob2 = 'set', 1, 0)) AS succeeded, max(if(blob2 IN (${failureActions}), 1, 0)) AS failed FROM app_log WHERE ${window} AND (blob2 = 'set' OR blob2 IN (${failureActions})) GROUP BY date, app_id, device_id) GROUP BY date` | ||
| const failuresQuery = `SELECT action, count() AS devices FROM (SELECT ${day} AS date, blob2 AS action, index1 AS app_id, blob1 AS device_id FROM app_log WHERE ${window} AND blob2 IN (${failureActions}) GROUP BY date, action, app_id, device_id) GROUP BY action` | ||
| const platformsQuery = `SELECT platform, count() AS devices FROM (SELECT double1 AS platform, index1 AS app_id, blob1 AS device_id FROM device_usage WHERE ${window} AND double1 IN (0.0, 1.0, 2.0) GROUP BY platform, app_id, device_id) GROUP BY platform` | ||
| const updaterVersionsQuery = `SELECT date, version, count() AS devices FROM (SELECT ${day} AS date, index1 AS app_id, blob1 AS device_id, argMax(blob3, timestamp) AS version FROM device_info WHERE ${window} AND blob3 != '' GROUP BY date, app_id, device_id) GROUP BY date, version` | ||
|
|
||
| try { | ||
| const [outcomeRows, failureRows, platformRows, versionRows] = await Promise.all([ | ||
| runQueryToCFA<{ date: string, successes: number, failures: number }>(c, outcomesQuery), | ||
| const [failureRows, platformRows, versionRows] = await Promise.all([ | ||
| runQueryToCFA<{ action: string, devices: number }>(c, failuresQuery), | ||
| runQueryToCFA<{ platform: number, devices: number }>(c, platformsQuery), | ||
| runQueryToCFA<{ date: string, version: string, devices: number }>(c, updaterVersionsQuery), | ||
| ]) | ||
| const daily = outcomeRows.map((row) => { | ||
| const successes = Number(row.successes) || 0 | ||
| const failures = Number(row.failures) || 0 | ||
| const outcomes = successes + failures | ||
| return { date: row.date, success_rate: outcomes ? (successes / outcomes) * 100 : 0 } | ||
| }).sort((a, b) => a.date.localeCompare(b.date)) | ||
| const totalSuccesses = outcomeRows.reduce((sum, row) => sum + (Number(row.successes) || 0), 0) | ||
| const totalFailures = outcomeRows.reduce((sum, row) => sum + (Number(row.failures) || 0), 0) | ||
| const totalOutcomes = totalSuccesses + totalFailures | ||
| const success_rate = totalOutcomes ? (totalSuccesses / totalOutcomes) * 100 : 0 | ||
| const failureTotal = failureRows.reduce((sum, row) => sum + (Number(row.devices) || 0), 0) | ||
| const failures = failureRows | ||
| .map(row => ({ reason: row.action, share: failureTotal ? ((Number(row.devices) || 0) / failureTotal) * 100 : 0 })) | ||
|
|
@@ -2652,8 +2643,6 @@ export async function getPublicLiveUpdateMetricsCF(c: Context, referenceDate = n | |
| for (const row of versionRows) | ||
| versionTotals.set(row.date, (versionTotals.get(row.date) ?? 0) + (Number(row.devices) || 0)) | ||
| return { | ||
| success_rate, | ||
| daily, | ||
| failures, | ||
| platforms, | ||
| updater_versions: versionRows | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
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.
P2: During daily shard processing,
/live_updatescan still show a success rate that differs from admin because this query admits partially completedglobal_statsrows that the admin query excludes. Filtering oncompleted_shardswithREQUIRED_GLOBAL_STATS_SHARDSkeeps the KPI and daily series aligned with admin.Prompt for AI agents