@@ -33,6 +33,7 @@ import {
3333 HeartbeatStorage ,
3434 SingleDateHeartbeat
3535} from './types' ;
36+ import { logger } from './logger' ;
3637
3738const MAX_HEADER_BYTES = 1024 ;
3839// 30 days
@@ -80,43 +81,47 @@ export class HeartbeatServiceImpl implements HeartbeatService {
8081 * already logged, subsequent calls to this function in the same day will be ignored.
8182 */
8283 async triggerHeartbeat ( ) : Promise < void > {
83- const platformLogger = this . container
84- . getProvider ( 'platform-logger' )
85- . getImmediate ( ) ;
84+ try {
85+ const platformLogger = this . container
86+ . getProvider ( 'platform-logger' )
87+ . getImmediate ( ) ;
8688
87- // This is the "Firebase user agent" string from the platform logger
88- // service, not the browser user agent.
89- const agent = platformLogger . getPlatformInfoString ( ) ;
90- const date = getUTCDateString ( ) ;
91- if ( this . _heartbeatsCache ?. heartbeats == null ) {
92- this . _heartbeatsCache = await this . _heartbeatsCachePromise ;
93- // If we failed to construct a heartbeats cache, then return immediately.
89+ // This is the "Firebase user agent" string from the platform logger
90+ // service, not the browser user agent.
91+ const agent = platformLogger . getPlatformInfoString ( ) ;
92+ const date = getUTCDateString ( ) ;
93+ console . log ( 'heartbeats' , this . _heartbeatsCache ?. heartbeats ) ;
9494 if ( this . _heartbeatsCache ?. heartbeats == null ) {
95+ this . _heartbeatsCache = await this . _heartbeatsCachePromise ;
96+ // If we failed to construct a heartbeats cache, then return immediately.
97+ if ( this . _heartbeatsCache ?. heartbeats == null ) {
98+ return ;
99+ }
100+ }
101+ // Do not store a heartbeat if one is already stored for this day
102+ // or if a header has already been sent today.
103+ if (
104+ this . _heartbeatsCache . lastSentHeartbeatDate === date ||
105+ this . _heartbeatsCache . heartbeats . some (
106+ singleDateHeartbeat => singleDateHeartbeat . date === date
107+ )
108+ ) {
95109 return ;
110+ } else {
111+ // There is no entry for this date. Create one.
112+ this . _heartbeatsCache . heartbeats . push ( { date, agent } ) ;
96113 }
114+ // Remove entries older than 30 days.
115+ this . _heartbeatsCache . heartbeats =
116+ this . _heartbeatsCache . heartbeats . filter ( singleDateHeartbeat => {
117+ const hbTimestamp = new Date ( singleDateHeartbeat . date ) . valueOf ( ) ;
118+ const now = Date . now ( ) ;
119+ return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS ;
120+ } ) ;
121+ return this . _storage . overwrite ( this . _heartbeatsCache ) ;
122+ } catch ( e ) {
123+ logger . warn ( e ) ;
97124 }
98- // Do not store a heartbeat if one is already stored for this day
99- // or if a header has already been sent today.
100- if (
101- this . _heartbeatsCache . lastSentHeartbeatDate === date ||
102- this . _heartbeatsCache . heartbeats . some (
103- singleDateHeartbeat => singleDateHeartbeat . date === date
104- )
105- ) {
106- return ;
107- } else {
108- // There is no entry for this date. Create one.
109- this . _heartbeatsCache . heartbeats . push ( { date, agent } ) ;
110- }
111- // Remove entries older than 30 days.
112- this . _heartbeatsCache . heartbeats = this . _heartbeatsCache . heartbeats . filter (
113- singleDateHeartbeat => {
114- const hbTimestamp = new Date ( singleDateHeartbeat . date ) . valueOf ( ) ;
115- const now = Date . now ( ) ;
116- return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS ;
117- }
118- ) ;
119- return this . _storage . overwrite ( this . _heartbeatsCache ) ;
120125 }
121126
122127 /**
@@ -127,39 +132,44 @@ export class HeartbeatServiceImpl implements HeartbeatService {
127132 * returns an empty string.
128133 */
129134 async getHeartbeatsHeader ( ) : Promise < string > {
130- if ( this . _heartbeatsCache === null ) {
131- await this . _heartbeatsCachePromise ;
132- }
133- // If it's still null or the array is empty, there is no data to send.
134- if (
135- this . _heartbeatsCache ?. heartbeats == null ||
136- this . _heartbeatsCache . heartbeats . length === 0
137- ) {
135+ try {
136+ if ( this . _heartbeatsCache === null ) {
137+ await this . _heartbeatsCachePromise ;
138+ }
139+ // If it's still null or the array is empty, there is no data to send.
140+ if (
141+ this . _heartbeatsCache ?. heartbeats == null ||
142+ this . _heartbeatsCache . heartbeats . length === 0
143+ ) {
144+ return '' ;
145+ }
146+ const date = getUTCDateString ( ) ;
147+ // Extract as many heartbeats from the cache as will fit under the size limit.
148+ const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader (
149+ this . _heartbeatsCache . heartbeats
150+ ) ;
151+ const headerString = base64urlEncodeWithoutPadding (
152+ JSON . stringify ( { version : 2 , heartbeats : heartbeatsToSend } )
153+ ) ;
154+ // Store last sent date to prevent another being logged/sent for the same day.
155+ this . _heartbeatsCache . lastSentHeartbeatDate = date ;
156+ if ( unsentEntries . length > 0 ) {
157+ // Store any unsent entries if they exist.
158+ this . _heartbeatsCache . heartbeats = unsentEntries ;
159+ // This seems more likely than emptying the array (below) to lead to some odd state
160+ // since the cache isn't empty and this will be called again on the next request,
161+ // and is probably safest if we await it.
162+ await this . _storage . overwrite ( this . _heartbeatsCache ) ;
163+ } else {
164+ this . _heartbeatsCache . heartbeats = [ ] ;
165+ // Do not wait for this, to reduce latency.
166+ void this . _storage . overwrite ( this . _heartbeatsCache ) ;
167+ }
168+ return headerString ;
169+ } catch ( e ) {
170+ logger . warn ( e ) ;
138171 return '' ;
139172 }
140- const date = getUTCDateString ( ) ;
141- // Extract as many heartbeats from the cache as will fit under the size limit.
142- const { heartbeatsToSend, unsentEntries } = extractHeartbeatsForHeader (
143- this . _heartbeatsCache . heartbeats
144- ) ;
145- const headerString = base64urlEncodeWithoutPadding (
146- JSON . stringify ( { version : 2 , heartbeats : heartbeatsToSend } )
147- ) ;
148- // Store last sent date to prevent another being logged/sent for the same day.
149- this . _heartbeatsCache . lastSentHeartbeatDate = date ;
150- if ( unsentEntries . length > 0 ) {
151- // Store any unsent entries if they exist.
152- this . _heartbeatsCache . heartbeats = unsentEntries ;
153- // This seems more likely than emptying the array (below) to lead to some odd state
154- // since the cache isn't empty and this will be called again on the next request,
155- // and is probably safest if we await it.
156- await this . _storage . overwrite ( this . _heartbeatsCache ) ;
157- } else {
158- this . _heartbeatsCache . heartbeats = [ ] ;
159- // Do not wait for this, to reduce latency.
160- void this . _storage . overwrite ( this . _heartbeatsCache ) ;
161- }
162- return headerString ;
163173 }
164174}
165175
0 commit comments