Skip to content

Commit 2142867

Browse files
committed
fix(serverless-api/logs): change log polling cache
1 parent 6f3ad06 commit 2142867

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

packages/serverless-api/src/streams/logs.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Readable } from 'stream';
22
import { listOnePageLogResources } from '../api/logs';
3-
import { Sid } from '../types';
43
import { TwilioServerlessApiClient } from '../client';
4+
import { Sid } from '../types';
55
import { LogsConfig } from '../types/logs';
66

77
export class LogsStream extends Readable {
88
private _pollingFrequency: number;
9+
private _pollingCacheSize: number;
910
private _interval: NodeJS.Timeout | undefined;
1011
private _viewedSids: Set<Sid>;
1112

@@ -19,6 +20,7 @@ export class LogsStream extends Readable {
1920
this._interval = undefined;
2021
this._viewedSids = new Set();
2122
this._pollingFrequency = config.pollingFrequency || 1000;
23+
this._pollingCacheSize = config.logCacheSize || 1000;
2224
}
2325

2426
set pollingFrequency(frequency: number) {
@@ -43,17 +45,22 @@ export class LogsStream extends Readable {
4345
}
4446
);
4547
logs
46-
.filter((log) => !this._viewedSids.has(log.sid))
48+
.filter(log => !this._viewedSids.has(log.sid))
4749
.reverse()
48-
.forEach((log) => {
50+
.forEach(log => {
4951
this.push(log);
5052
});
51-
// Replace the set each time rather than adding to the set.
52-
// This way the set is always the size of a page of logs and the next page
53-
// will either overlap or not. This is instead of keeping an ever growing
54-
// set of viewSids which would cause memory issues for long running log
55-
// tails.
56-
this._viewedSids = new Set(logs.map((log) => log.sid));
53+
54+
// The logs endpoint is not reliably returning logs in the same order
55+
// Therefore we need to keep a set of all previously seen log entries
56+
// In order to avoid memory leaks we cap the total size of logs at 1000
57+
// If the new set is larger we'll instead only use the SIDs from the current
58+
// request.
59+
if (logs.length + this._viewedSids.size <= this._pollingCacheSize) {
60+
logs.map(log => log.sid).forEach(sid => this._viewedSids.add(sid));
61+
} else {
62+
this._viewedSids = new Set(logs.map(log => log.sid));
63+
}
5764
if (!this.config.tail) {
5865
this.push(null);
5966
}

packages/serverless-api/src/types/logs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export type LogsConfig = {
99
limit?: number;
1010
filterByFunction?: string | Sid;
1111
pollingFrequency?: number;
12+
logCacheSize?: number;
1213
};
1314

1415
export type LogFilters = {

0 commit comments

Comments
 (0)