@@ -4,60 +4,43 @@ import type { TelemetryDeps } from '../telemetry-deps'
44import type TelemetryTypes from '../telemetry-types'
55
66/**
7- * Builds `$.telemetry`: `log` and `mark` check the entry, authorize once, build
8- * the first-party row and POST it to the ingest.
7+ * Builds `$.telemetry`: `log` and `mark` check the entry, read the environment
8+ * and authorize afresh, build the first-party row and POST it to the ingest.
99 *
10- * One POST per call, none batched, one attempt; a session with no credential to
11- * authorize, or an ingest that refuses, rejects the caller's promise. A failed
12- * authorize or environment read is not memoized, so a later call retries it .
10+ * One POST per call, rows one after another, nothing kept between them: a
11+ * session that has moved to a third-party provider or a gateway, or turned
12+ * analytics off, sends nothing more; no credential or a refusal rejects .
1313 *
1414 * @param deps the calls on the nouns beneath
15- * @returns the `$.telemetry` interface, `log` and `mark`, each authorizing once
16- * (memoized) before it posts
15+ * @returns the `$.telemetry` interface, `log` and `mark`
1716 */
1817export function telemetryOf ( deps : TelemetryDeps ) : TelemetryTypes . Telemetry {
19- let held : ReturnType < TelemetryDeps [ 'authorize' ] > | undefined
20- let read : ReturnType < TelemetryDeps [ 'environment' ] > | undefined
18+ let queue : Promise < unknown > = Promise . resolve ( )
2119
2220 async function post (
2321 fields : Entries . Fields ,
2422 method : TelemetryTypes . Method ,
2523 ) : Promise < void > {
26- read ??= deps . environment ( ) . catch ( ( error : unknown ) => {
27- read = undefined
28-
29- throw error
30- } )
31- const environment = await read
24+ const environment = await deps . environment ( )
3225
3326 if ( isAnalyticsOff ( environment ) ) {
3427 return
3528 }
3629
37- if ( ! held ) {
38- held = deps . authorize ( ) . catch ( ( error : unknown ) => {
39- held = undefined
40-
41- throw error
42- } )
43- }
44-
45- const auth = await held
30+ const body = Entries . batchOf ( fields , {
31+ sessionId : await deps . id ( ) ,
32+ model : await deps . model ( ) ,
33+ userType : environment . userType === 'ant' ? 'ant' : 'external' ,
34+ } )
35+ const auth = await deps . authorize ( )
4636
4737 if ( ! auth ) {
48- held = undefined
49-
5038 throw Entries . refusal (
5139 'this session has no first-party credential to authorize' ,
5240 method ,
5341 )
5442 }
5543
56- const body = Entries . batchOf ( fields , {
57- sessionId : await deps . id ( ) ,
58- model : await deps . model ( ) ,
59- userType : environment . userType === 'ant' ? 'ant' : 'external' ,
60- } )
6144 const response = await deps . fetch ( Entries . INGEST_URL , {
6245 method : 'POST' ,
6346 headers : {
@@ -73,8 +56,18 @@ export function telemetryOf(deps: TelemetryDeps): TelemetryTypes.Telemetry {
7356 }
7457 }
7558
59+ function queued (
60+ fields : Entries . Fields ,
61+ method : TelemetryTypes . Method ,
62+ ) : Promise < void > {
63+ const turn = queue . then ( ( ) => post ( fields , method ) )
64+ queue = turn . catch ( ( ) => undefined )
65+
66+ return turn
67+ }
68+
7669 return {
77- log : async entry => post ( Entries . checkedFields ( entry ) , 'log' ) ,
78- mark : async entry => post ( Entries . checkedMark ( entry ) , 'mark' ) ,
70+ log : async entry => queued ( Entries . checkedFields ( entry ) , 'log' ) ,
71+ mark : async entry => queued ( Entries . checkedMark ( entry ) , 'mark' ) ,
7972 }
8073}
0 commit comments