@@ -33,6 +33,7 @@ import {
33
33
HeartbeatStorage ,
34
34
SingleDateHeartbeat
35
35
} from './types' ;
36
+ import { logger } from './logger' ;
36
37
37
38
const MAX_HEADER_BYTES = 1024 ;
38
39
// 30 days
@@ -80,43 +81,47 @@ export class HeartbeatServiceImpl implements HeartbeatService {
80
81
* already logged, subsequent calls to this function in the same day will be ignored.
81
82
*/
82
83
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 ( ) ;
86
88
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 ) ;
94
94
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
+ ) {
95
109
return ;
110
+ } else {
111
+ // There is no entry for this date. Create one.
112
+ this . _heartbeatsCache . heartbeats . push ( { date, agent } ) ;
96
113
}
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 ) ;
97
124
}
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 ) ;
120
125
}
121
126
122
127
/**
@@ -127,39 +132,44 @@ export class HeartbeatServiceImpl implements HeartbeatService {
127
132
* returns an empty string.
128
133
*/
129
134
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 ) ;
138
171
return '' ;
139
172
}
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 ;
163
173
}
164
174
}
165
175
0 commit comments