@@ -3,9 +3,21 @@ import { listOnePageLogResources } from '../api/logs';
33import { TwilioServerlessApiClient } from '../client' ;
44import { Sid } from '../types' ;
55import { LogsConfig } from '../types/logs' ;
6+ import debug from 'debug' ;
7+
8+ const log = debug ( 'twilio-serverless-api:client:logs' ) ;
9+
10+ const pollsBeforeBackOff = 10 ;
11+ const defaultPollingFrequency = 1000 ;
12+ // This default max allows the command to get to polling once every 32 seconds
13+ const defaultMaxPollingFrequency = 30000 ;
14+ const defaultLogCacheSize = 1000 ;
615
716export class LogsStream extends Readable {
17+ private _initialPollingFrequency : number ;
818 private _pollingFrequency : number ;
19+ private _maxPollingFrequency : number ;
20+ private _pollsWithoutResults : number ;
921 private _pollingCacheSize : number ;
1022 private _interval : NodeJS . Timeout | undefined ;
1123 private _viewedSids : Set < Sid > ;
@@ -21,8 +33,12 @@ export class LogsStream extends Readable {
2133 this . _interval = undefined ;
2234 this . _viewedSids = new Set ( ) ;
2335 this . _viewedLogs = [ ] ;
24- this . _pollingFrequency = config . pollingFrequency || 1000 ;
25- this . _pollingCacheSize = config . logCacheSize || 1000 ;
36+ this . _pollingFrequency = this . _initialPollingFrequency =
37+ config . pollingFrequency || defaultPollingFrequency ;
38+ this . _maxPollingFrequency =
39+ config . maxPollingFrequency || defaultMaxPollingFrequency ;
40+ this . _pollsWithoutResults = 0 ;
41+ this . _pollingCacheSize = config . logCacheSize || defaultLogCacheSize ;
2642 }
2743
2844 set pollingFrequency ( frequency : number ) {
@@ -46,12 +62,33 @@ export class LogsStream extends Readable {
4662 pageSize : this . config . limit ,
4763 }
4864 ) ;
49- logs
50- . filter ( log => ! this . _viewedSids . has ( log . sid ) )
51- . reverse ( )
52- . forEach ( log => {
65+ const unviewedLogs = logs . filter ( ( log ) => ! this . _viewedSids . has ( log . sid ) ) ;
66+ if ( unviewedLogs . length > 0 ) {
67+ this . _pollsWithoutResults = 0 ;
68+ this . pollingFrequency = this . _initialPollingFrequency ;
69+ log (
70+ `New log received. Now polling once every ${ this . _pollingFrequency } milliseconds.`
71+ ) ;
72+ unviewedLogs . reverse ( ) . forEach ( ( log ) => {
5373 this . push ( log ) ;
5474 } ) ;
75+ } else {
76+ if ( this . _pollsWithoutResults < pollsBeforeBackOff ) {
77+ this . _pollsWithoutResults ++ ;
78+ } else {
79+ if ( this . _pollingFrequency < this . _maxPollingFrequency ) {
80+ log (
81+ `No new logs for ${
82+ this . _pollsWithoutResults * this . _pollingFrequency
83+ } milliseconds. Now polling once every ${
84+ this . _pollingFrequency * 2
85+ } milliseconds.`
86+ ) ;
87+ this . pollingFrequency = this . _pollingFrequency * 2 ;
88+ this . _pollsWithoutResults = 0 ;
89+ }
90+ }
91+ }
5592
5693 // The logs endpoint is not reliably returning logs in the same order
5794 // Therefore we need to keep a set of all previously seen log entries
@@ -68,22 +105,22 @@ export class LogsStream extends Readable {
68105 // and new logs by stringifying the sid and the date together.
69106 const viewedLogsSet = new Set ( [
70107 ...this . _viewedLogs . map (
71- log => `${ log . sid } -${ log . dateCreated . toISOString ( ) } `
108+ ( log ) => `${ log . sid } -${ log . dateCreated . toISOString ( ) } `
72109 ) ,
73- ...logs . map ( log => `${ log . sid } -${ log . date_created } ` ) ,
110+ ...logs . map ( ( log ) => `${ log . sid } -${ log . date_created } ` ) ,
74111 ] ) ;
75112 // Then we take that set, map over the logs and split them up into sid and
76113 // date again, sort them most to least recent and chop off the oldest if
77114 // they are beyond the polling cache size.
78115 this . _viewedLogs = [ ...viewedLogsSet ]
79- . map ( logString => {
116+ . map ( ( logString ) => {
80117 const [ sid , dateCreated ] = logString . split ( '-' ) ;
81118 return { sid, dateCreated : new Date ( dateCreated ) } ;
82119 } )
83120 . sort ( ( a , b ) => b . dateCreated . valueOf ( ) - a . dateCreated . valueOf ( ) )
84121 . slice ( 0 , this . _pollingCacheSize ) ;
85122 // Finally we create a set of just SIDs to compare against.
86- this . _viewedSids = new Set ( this . _viewedLogs . map ( log => log . sid ) ) ;
123+ this . _viewedSids = new Set ( this . _viewedLogs . map ( ( log ) => log . sid ) ) ;
87124
88125 if ( ! this . config . tail ) {
89126 this . push ( null ) ;
0 commit comments