@@ -20,65 +20,62 @@ const INCREMENTAL_LOOKBACK_MS = 2 * 3_600_000
2020export type SyncStatsResult = { ok : true ; rows : number ; startedAt : string ; periodStart : string ; periodEnd : string }
2121export type SyncStatsError = AthenaQueryError | AthenaQueryTimeoutError | DatabaseError
2222
23- export const syncStats : ( options ?: { full ?: boolean } ) => Effect . Effect <
24- SyncStatsResult ,
25- SyncStatsError ,
26- Athena | ModelStatRepo | ProviderStatRepo | GeoStatRepo
27- > = Effect . fn ( "StatSync.sync" ) ( function * ( options ?: { full ?: boolean } ) {
28- const startedAt = yield * DateTime . nowAsDate
29- const periodEnd = new Date ( Math . floor ( ( startedAt . getTime ( ) - DATALAKE_INGESTION_LAG_MS ) / 60_000 ) * 60_000 )
30- const periodStart = options ?. full ? fullPeriodStart ( periodEnd ) : incrementalPeriodStart ( periodEnd )
31- const athena = yield * Athena
32- const modelStats = yield * ModelStatRepo
33- const providerStats = yield * ProviderStatRepo
34- const geoStats = yield * GeoStatRepo
23+ export const syncStats : ( options ?: {
24+ full ?: boolean
25+ } ) => Effect . Effect < SyncStatsResult , SyncStatsError , Athena | ModelStatRepo | ProviderStatRepo | GeoStatRepo > =
26+ Effect . fn ( "StatSync.sync" ) ( function * ( options ?: { full ?: boolean } ) {
27+ const startedAt = yield * DateTime . nowAsDate
28+ const periodEnd = new Date ( Math . floor ( ( startedAt . getTime ( ) - DATALAKE_INGESTION_LAG_MS ) / 60_000 ) * 60_000 )
29+ const periodStart = options ?. full ? fullPeriodStart ( periodEnd ) : incrementalPeriodStart ( periodEnd )
30+ const athena = yield * Athena
31+ const modelStats = yield * ModelStatRepo
32+ const providerStats = yield * ProviderStatRepo
33+ const geoStats = yield * GeoStatRepo
3534
36- yield * logRuntimeCheck ( )
35+ yield * logRuntimeCheck ( )
3736
38- const rows = yield * athena . query ( buildStatsQuery ( periodStart , periodEnd ) )
39- const modelRows = modelRowsFromAggregates (
40- rows . filter ( ( row ) => row . dimension === "model" ) . flatMap ( toModelAggregate ) ,
41- )
42- const providerRows = providerRowsFromAggregates (
43- rows . filter ( ( row ) => row . dimension === "provider" ) . flatMap ( toProviderAggregate ) ,
44- )
45- const geoRows = geoRowsFromAggregates (
46- rows . filter ( ( row ) => row . dimension === "geo" || row . dimension === "geo_model" ) . flatMap ( toGeoAggregate ) ,
47- )
37+ const rows = yield * athena . query ( buildStatsQuery ( periodStart , periodEnd ) )
38+ const modelRows = modelRowsFromAggregates ( rows . filter ( ( row ) => row . dimension === "model" ) . flatMap ( toModelAggregate ) )
39+ const providerRows = providerRowsFromAggregates (
40+ rows . filter ( ( row ) => row . dimension === "provider" ) . flatMap ( toProviderAggregate ) ,
41+ )
42+ const geoRows = geoRowsFromAggregates (
43+ rows . filter ( ( row ) => row . dimension === "geo" || row . dimension === "geo_model" ) . flatMap ( toGeoAggregate ) ,
44+ )
4845
49- yield * Effect . all ( [ modelStats . upsert ( modelRows ) , providerStats . upsert ( providerRows ) , geoStats . upsert ( geoRows ) ] , {
50- concurrency : "unbounded" ,
51- discard : true ,
52- } )
53- yield * Effect . all (
54- [
55- modelStats . deleteRetiredDimensions ( modelRows ) ,
56- providerStats . deleteRetiredDimensions ( providerRows ) ,
57- geoStats . deleteRetiredDimensions ( geoRows ) ,
58- ] ,
59- { concurrency : "unbounded" , discard : true } ,
60- )
46+ yield * Effect . all ( [ modelStats . upsert ( modelRows ) , providerStats . upsert ( providerRows ) , geoStats . upsert ( geoRows ) ] , {
47+ concurrency : "unbounded" ,
48+ discard : true ,
49+ } )
50+ yield * Effect . all (
51+ [
52+ modelStats . deleteRetiredDimensions ( modelRows ) ,
53+ providerStats . deleteRetiredDimensions ( providerRows ) ,
54+ geoStats . deleteRetiredDimensions ( geoRows ) ,
55+ ] ,
56+ { concurrency : "unbounded" , discard : true } ,
57+ )
58+
59+ yield * Effect . logInfo (
60+ `stats sync complete ${ JSON . stringify ( {
61+ startedAt : startedAt . toISOString ( ) ,
62+ periodStart : periodStart . toISOString ( ) ,
63+ periodEnd : periodEnd . toISOString ( ) ,
64+ rows : modelRows . length ,
65+ providerRows : providerRows . length ,
66+ geoRows : geoRows . length ,
67+ stage : Resource . App . stage ,
68+ } ) } `,
69+ )
6170
62- yield * Effect . logInfo (
63- `stats sync complete ${ JSON . stringify ( {
71+ return {
72+ ok : true ,
73+ rows : modelRows . length ,
6474 startedAt : startedAt . toISOString ( ) ,
6575 periodStart : periodStart . toISOString ( ) ,
6676 periodEnd : periodEnd . toISOString ( ) ,
67- rows : modelRows . length ,
68- providerRows : providerRows . length ,
69- geoRows : geoRows . length ,
70- stage : Resource . App . stage ,
71- } ) } `,
72- )
73-
74- return {
75- ok : true ,
76- rows : modelRows . length ,
77- startedAt : startedAt . toISOString ( ) ,
78- periodStart : periodStart . toISOString ( ) ,
79- periodEnd : periodEnd . toISOString ( ) ,
80- }
81- } )
77+ }
78+ } )
8279
8380// May 27 was partial, so keep Athena stats anchored at the first complete day.
8481function fullPeriodStart ( periodEnd : Date ) {
@@ -96,10 +93,7 @@ function fullPeriodStart(periodEnd: Date) {
9693// dimension cleanup).
9794function incrementalPeriodStart ( periodEnd : Date ) {
9895 return new Date (
99- Math . max (
100- startOfIsoWeek ( new Date ( periodEnd . getTime ( ) - INCREMENTAL_LOOKBACK_MS ) ) . getTime ( ) ,
101- STATS_DATA_START_MS ,
102- ) ,
96+ Math . max ( startOfIsoWeek ( new Date ( periodEnd . getTime ( ) - INCREMENTAL_LOOKBACK_MS ) ) . getTime ( ) , STATS_DATA_START_MS ) ,
10397 )
10498}
10599
0 commit comments