Skip to content

Commit f964a69

Browse files
authored
docs(core): Add flush-related docstrings and comments (#3789)
Annotations added in the process of making sense of the code while debugging something else. In addition to docstrings and comments, the only changes are: - s/`_isClientProcessing`/`_isClientDoneProcessing`: This resolves to `true` when processing is done, and `false` if processing is still happening, which is the opposite of what the original name implied. - s/`_processing`/`_numProcessing`: Since it represents a number, might as well make that obvious in the name, lest the casual reader think it might be a boolean or a collection of things currently being processed. - s/`ready`/`clientFinished` in `flush`: This provides a nice parallel to `transportFlushed`. Also, the client may well be "ready," but since this is mostly called as part of a shutdown procedure, the fact that it's ready matters less than the fact that it's finished with the work it was doing.
1 parent 779818e commit f964a69

File tree

2 files changed

+41
-19
lines changed

2 files changed

+41
-19
lines changed

packages/core/src/baseclient.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
7676
/** Array of used integrations. */
7777
protected _integrations: IntegrationIndex = {};
7878

79-
/** Number of call being processed */
80-
protected _processing: number = 0;
79+
/** Number of calls being processed */
80+
protected _numProcessing: number = 0;
8181

8282
/**
8383
* Initializes this client instance.
@@ -185,11 +185,11 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
185185
* @inheritDoc
186186
*/
187187
public flush(timeout?: number): PromiseLike<boolean> {
188-
return this._isClientProcessing(timeout).then(ready => {
188+
return this._isClientDoneProcessing(timeout).then(clientFinished => {
189189
return this._getBackend()
190190
.getTransport()
191191
.close(timeout)
192-
.then(transportFlushed => ready && transportFlushed);
192+
.then(transportFlushed => clientFinished && transportFlushed);
193193
});
194194
}
195195

@@ -262,14 +262,23 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
262262
this._getBackend().sendSession(session);
263263
}
264264

265-
/** Waits for the client to be done with processing. */
266-
protected _isClientProcessing(timeout?: number): PromiseLike<boolean> {
265+
/**
266+
* Determine if the client is finished processing. Returns a promise because it will wait `timeout` ms before saying
267+
* "no" (resolving to `false`) in order to give the client a chance to potentially finish first.
268+
*
269+
* @param timeout The time, in ms, after which to resolve to `false` if the client is still busy. Passing `0` (or not
270+
* passing anything) will make the promise wait as long as it takes for processing to finish before resolving to
271+
* `true`.
272+
* @returns A promise which will resolve to `true` if processing is already done or finishes before the timeout, and
273+
* `false` otherwise
274+
*/
275+
protected _isClientDoneProcessing(timeout?: number): PromiseLike<boolean> {
267276
return new SyncPromise(resolve => {
268277
let ticked: number = 0;
269278
const tick: number = 1;
270279

271280
const interval = setInterval(() => {
272-
if (this._processing == 0) {
281+
if (this._numProcessing == 0) {
273282
clearInterval(interval);
274283
resolve(true);
275284
} else {
@@ -554,14 +563,14 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
554563
* Occupies the client with processing and event
555564
*/
556565
protected _process<T>(promise: PromiseLike<T>): void {
557-
this._processing += 1;
566+
this._numProcessing += 1;
558567
void promise.then(
559568
value => {
560-
this._processing -= 1;
569+
this._numProcessing -= 1;
561570
return value;
562571
},
563572
reason => {
564-
this._processing -= 1;
573+
this._numProcessing -= 1;
565574
return reason;
566575
},
567576
);

packages/utils/src/promisebuffer.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,40 @@ export class PromiseBuffer<T> {
1616
}
1717

1818
/**
19-
* Add a promise to the queue.
19+
* Add a promise (representing an in-flight action) to the queue, and set it to remove itself on fulfillment.
2020
*
21-
* @param taskProducer A function producing any PromiseLike<T>; In previous versions this used to be `task: PromiseLike<T>`,
22-
* however, Promises were instantly created on the call-site, making them fall through the buffer limit.
21+
* @param taskProducer A function producing any PromiseLike<T>; In previous versions this used to be `task:
22+
* PromiseLike<T>`, but under that model, Promises were instantly created on the call-site and their executor
23+
* functions therefore ran immediately. Thus, even if the buffer was full, the action still happened. By
24+
* requiring the promise to be wrapped in a function, we can defer promise creation until after the buffer
25+
* limit check.
2326
* @returns The original promise.
2427
*/
2528
public add(taskProducer: () => PromiseLike<T>): PromiseLike<T> {
2629
if (!this.isReady()) {
2730
return SyncPromise.reject(new SentryError('Not adding Promise due to buffer limit reached.'));
2831
}
32+
33+
// start the task and add its promise to the queue
2934
const task = taskProducer();
3035
if (this._buffer.indexOf(task) === -1) {
3136
this._buffer.push(task);
3237
}
3338
void task
3439
.then(() => this.remove(task))
40+
// Use `then(null, rejectionHandler)` rather than `catch(rejectionHandler)` so that we can use `PromiseLike`
41+
// rather than `Promise`. `PromiseLike` doesn't have a `.catch` method, making its polyfill smaller. (ES5 didn't
42+
// have promises, so TS has to polyfill when down-compiling.)
3543
.then(null, () =>
3644
this.remove(task).then(null, () => {
37-
// We have to add this catch here otherwise we have an unhandledPromiseRejection
38-
// because it's a new Promise chain.
45+
// We have to add another catch here because `this.remove()` starts a new promise chain.
3946
}),
4047
);
4148
return task;
4249
}
4350

4451
/**
45-
* Remove a promise to the queue.
52+
* Remove a promise from the queue.
4653
*
4754
* @param task Can be any PromiseLike<T>
4855
* @returns Removed promise.
@@ -60,18 +67,24 @@ export class PromiseBuffer<T> {
6067
}
6168

6269
/**
63-
* This will drain the whole queue, returns true if queue is empty or drained.
64-
* If timeout is provided and the queue takes longer to drain, the promise still resolves but with false.
70+
* Wait for all promises in the queue to resolve or for timeout to expire, whichever comes first.
6571
*
66-
* @param timeout Number in ms to wait until it resolves with false.
72+
* @param timeout The time, in ms, after which to resolve to `false` if the queue is still non-empty. Passing `0` (or
73+
* not passing anything) will make the promise wait as long as it takes for the queue to drain before resolving to
74+
* `true`.
75+
* @returns A promise which will resolve to `true` if the queue is already empty or drains before the timeout, and
76+
* `false` otherwise
6777
*/
6878
public drain(timeout?: number): PromiseLike<boolean> {
6979
return new SyncPromise<boolean>(resolve => {
80+
// wait for `timeout` ms and then resolve to `false` (if not cancelled first)
7081
const capturedSetTimeout = setTimeout(() => {
7182
if (timeout && timeout > 0) {
7283
resolve(false);
7384
}
7485
}, timeout);
86+
87+
// if all promises resolve in time, cancel the timer and resolve to `true`
7588
void SyncPromise.all(this._buffer)
7689
.then(() => {
7790
clearTimeout(capturedSetTimeout);

0 commit comments

Comments
 (0)