@bugsnag/core-performance
Advanced tools
Comparing version 2.4.0 to 2.4.1
class BatchProcessor { | ||
constructor(delivery, configuration, retryQueue, sampler, probabilityManager, encoder) { | ||
this.batch = []; | ||
this.spans = []; | ||
this.timeout = null; | ||
this.flushQueue = Promise.resolve(); | ||
this.delivery = delivery; | ||
@@ -28,4 +29,4 @@ this.configuration = configuration; | ||
} | ||
this.batch.push(span); | ||
if (this.batch.length >= this.configuration.maximumBatchSize) { | ||
this.spans.push(span); | ||
if (this.spans.length >= this.configuration.maximumBatchSize) { | ||
this.flush(); | ||
@@ -39,35 +40,41 @@ } | ||
this.stop(); | ||
const batch = this.prepareBatch(); | ||
// we either had nothing in the batch originally or all spans were discarded | ||
if (!batch) { | ||
return; | ||
} | ||
const payload = await this.encoder.encode(batch); | ||
const batchTime = Date.now(); | ||
try { | ||
const response = await this.delivery.send(payload); | ||
if (response.samplingProbability !== undefined) { | ||
this.probabilityManager.setProbability(response.samplingProbability); | ||
this.flushQueue = this.flushQueue.then(async () => { | ||
if (this.probabilityManager.fetchingInitialProbability) { | ||
await this.probabilityManager.fetchingInitialProbability; | ||
} | ||
switch (response.state) { | ||
case 'success': | ||
this.retryQueue.flush(); | ||
break; | ||
case 'failure-discard': | ||
this.configuration.logger.warn('delivery failed'); | ||
break; | ||
case 'failure-retryable': | ||
this.configuration.logger.info('delivery failed, adding to retry queue'); | ||
this.retryQueue.add(payload, batchTime); | ||
break; | ||
default: | ||
response.state; | ||
const batch = this.prepareBatch(); | ||
// we either had nothing in the batch originally or all spans were discarded | ||
if (!batch) { | ||
return; | ||
} | ||
} | ||
catch (err) { | ||
this.configuration.logger.warn('delivery failed'); | ||
} | ||
const payload = await this.encoder.encode(batch); | ||
const batchTime = Date.now(); | ||
try { | ||
const response = await this.delivery.send(payload); | ||
if (response.samplingProbability !== undefined) { | ||
this.probabilityManager.setProbability(response.samplingProbability); | ||
} | ||
switch (response.state) { | ||
case 'success': | ||
this.retryQueue.flush(); | ||
break; | ||
case 'failure-discard': | ||
this.configuration.logger.warn('delivery failed'); | ||
break; | ||
case 'failure-retryable': | ||
this.configuration.logger.info('delivery failed, adding to retry queue'); | ||
this.retryQueue.add(payload, batchTime); | ||
break; | ||
default: | ||
response.state; | ||
} | ||
} | ||
catch (err) { | ||
this.configuration.logger.warn('delivery failed'); | ||
} | ||
}); | ||
await this.flushQueue; | ||
} | ||
prepareBatch() { | ||
if (this.batch.length === 0) { | ||
if (this.spans.length === 0) { | ||
return; | ||
@@ -78,3 +85,3 @@ } | ||
const probability = this.sampler.spanProbability; | ||
for (const span of this.batch) { | ||
for (const span of this.spans) { | ||
if (span.samplingProbability.raw > probability.raw) { | ||
@@ -88,3 +95,3 @@ span.samplingProbability = probability; | ||
// clear out the current batch so we're ready to start a new one | ||
this.batch = []; | ||
this.spans = []; | ||
// if every span was discarded there's nothing to send | ||
@@ -91,0 +98,0 @@ if (batch.length === 0) { |
@@ -1,2 +0,2 @@ | ||
import { isStringWithLength, isString, isLogger, isStringArray, isNumber, isPluginArray, isObject } from './validation.js'; | ||
import { isStringWithLength, isString, isLogger, isStringArray, isPluginArray, isObject } from './validation.js'; | ||
@@ -39,7 +39,2 @@ const schema = { | ||
}, | ||
samplingProbability: { | ||
defaultValue: 1.0, | ||
message: 'should be a number between 0 and 1', | ||
validate: (value) => isNumber(value) && value >= 0 && value <= 1 | ||
}, | ||
plugins: { | ||
@@ -46,0 +41,0 @@ defaultValue: [], |
@@ -15,3 +15,3 @@ export { ResourceAttributes, SpanAttributes, attributeToJson } from './attributes.js'; | ||
export { timeToNumber } from './time.js'; | ||
export { isBoolean, isDeviceId, isLogger, isNumber, isObject, isPersistedProbability, isPlugin, isPluginArray, isSpanContext, isString, isStringArray, isStringOrRegExpArray, isStringWithLength, isTime } from './validation.js'; | ||
export { isBoolean, isLogger, isNumber, isObject, isPersistedProbability, isPlugin, isPluginArray, isSpanContext, isString, isStringArray, isStringOrRegExpArray, isStringWithLength, isTime } from './validation.js'; | ||
export { default as traceIdToSamplingRate } from './trace-id-to-sampling-rate.js'; |
@@ -1,2 +0,3 @@ | ||
import { isDeviceId, isPersistedProbability } from './validation.js'; | ||
import { isCuid } from '@bugsnag/cuid'; | ||
import { isPersistedProbability } from './validation.js'; | ||
@@ -23,3 +24,3 @@ class InMemoryPersistence { | ||
case 'bugsnag-anonymous-id': | ||
return isDeviceId(raw) | ||
return isCuid(raw) | ||
? raw | ||
@@ -26,0 +27,0 @@ : undefined; |
@@ -7,3 +7,3 @@ // the time between requests to fetch a new probability value from the server | ||
let initialProbabilityTime; | ||
let initialTimoutDuration; | ||
let initialTimeoutDuration; | ||
if (persistedProbability === undefined) { | ||
@@ -15,3 +15,3 @@ // If there is no stored probability: | ||
// - Immediately fetch a new probability value | ||
initialTimoutDuration = 0; | ||
initialTimeoutDuration = 0; | ||
} | ||
@@ -24,3 +24,3 @@ else if (persistedProbability.time < Date.now() - PROBABILITY_REFRESH_MILLISECONDS) { | ||
// - Immediately fetch a new probability value | ||
initialTimoutDuration = 0; | ||
initialTimeoutDuration = 0; | ||
} | ||
@@ -33,7 +33,7 @@ else { | ||
// - Fetch a new probability when this value would be 24 hours old | ||
initialTimoutDuration = PROBABILITY_REFRESH_MILLISECONDS - (Date.now() - initialProbabilityTime); | ||
initialTimeoutDuration = PROBABILITY_REFRESH_MILLISECONDS - (Date.now() - initialProbabilityTime); | ||
} | ||
return new ProbabilityManager(persistence, sampler, probabilityFetcher, initialTimoutDuration, initialProbabilityTime); | ||
return new ProbabilityManager(persistence, sampler, probabilityFetcher, initialTimeoutDuration, initialProbabilityTime); | ||
} | ||
constructor(persistence, sampler, probabilityFetcher, initialTimoutDuration, initialProbabilityTime) { | ||
constructor(persistence, sampler, probabilityFetcher, initialTimeoutDuration, initialProbabilityTime) { | ||
this.timeout = undefined; | ||
@@ -44,3 +44,8 @@ this.persistence = persistence; | ||
this.lastProbabilityTime = initialProbabilityTime; | ||
this.fetchNewProbabilityIn(initialTimoutDuration); | ||
if (initialTimeoutDuration === 0) { | ||
this.fetchingInitialProbability = new Promise((resolve) => { | ||
this.resolveInitialProbability = resolve; | ||
}); | ||
} | ||
this.fetchNewProbabilityIn(initialTimeoutDuration); | ||
} | ||
@@ -69,2 +74,8 @@ setProbability(newProbability) { | ||
} | ||
// Initial sampling request has been made, and we can unblock batching | ||
if (this.resolveInitialProbability) { | ||
this.resolveInitialProbability(); | ||
this.resolveInitialProbability = undefined; | ||
this.fetchingInitialProbability = undefined; | ||
} | ||
}, milliseconds); | ||
@@ -71,0 +82,0 @@ } |
@@ -8,3 +8,3 @@ import { type Configuration, type InternalConfiguration } from './config'; | ||
import { type SpanEnded } from './span'; | ||
type MinimalProbabilityManager = Pick<ProbabilityManager, 'setProbability'>; | ||
type MinimalProbabilityManager = Pick<ProbabilityManager, 'setProbability' | 'fetchingInitialProbability'>; | ||
export declare class BatchProcessor<C extends Configuration> implements Processor { | ||
@@ -17,4 +17,5 @@ private readonly delivery; | ||
private readonly encoder; | ||
private batch; | ||
private spans; | ||
private timeout; | ||
private flushQueue; | ||
constructor(delivery: Delivery, configuration: InternalConfiguration<C>, retryQueue: RetryQueue, sampler: ReadonlySampler, probabilityManager: MinimalProbabilityManager, encoder: TracePayloadEncoder<C>); | ||
@@ -21,0 +22,0 @@ private stop; |
@@ -15,3 +15,2 @@ import { type Plugin } from './plugin'; | ||
enabledReleaseStages?: string[] | null; | ||
samplingProbability?: number; | ||
plugins?: Array<Plugin<Configuration>>; | ||
@@ -38,3 +37,2 @@ } | ||
enabledReleaseStages: ConfigOption<string[] | null>; | ||
samplingProbability: ConfigOption<number>; | ||
plugins: ConfigOption<Array<Plugin<Configuration>>>; | ||
@@ -41,0 +39,0 @@ } |
@@ -11,2 +11,4 @@ import { type Persistence } from './persistence'; | ||
private timeout; | ||
fetchingInitialProbability: Promise<unknown> | undefined; | ||
private resolveInitialProbability?; | ||
private constructor(); | ||
@@ -13,0 +15,0 @@ setProbability(newProbability: number): Promise<void>; |
@@ -17,5 +17,4 @@ import { type Configuration, type Logger } from './config'; | ||
export declare function isTime(value: unknown): value is Time; | ||
export declare function isDeviceId(value: unknown): value is string; | ||
export declare function isPlugin(value: unknown): value is Plugin<unknown extends Configuration ? unknown : Configuration>; | ||
export declare function isPluginArray(value: unknown): value is Array<Plugin<unknown extends Configuration ? unknown : Configuration>>; | ||
//# sourceMappingURL=validation.d.ts.map |
@@ -25,8 +25,2 @@ const isBoolean = (value) => value === true || value === false; | ||
} | ||
// NOTE: this should be kept in sync with the notifier | ||
// https://github.com/bugsnag/bugsnag-js/blob/next/packages/plugin-browser-device/device.js | ||
function isDeviceId(value) { | ||
// make sure the persisted value looks like a valid cuid | ||
return typeof value === 'string' && /^c[a-z0-9]{20,32}$/.test(value); | ||
} | ||
function isPlugin(value) { | ||
@@ -39,2 +33,2 @@ return isObject(value) && typeof value.configure === 'function'; | ||
export { isBoolean, isDeviceId, isLogger, isNumber, isObject, isPersistedProbability, isPlugin, isPluginArray, isSpanContext, isString, isStringArray, isStringOrRegExpArray, isStringWithLength, isTime }; | ||
export { isBoolean, isLogger, isNumber, isObject, isPersistedProbability, isPlugin, isPluginArray, isSpanContext, isString, isStringArray, isStringOrRegExpArray, isStringWithLength, isTime }; |
{ | ||
"name": "@bugsnag/core-performance", | ||
"version": "2.4.0", | ||
"version": "2.4.1", | ||
"description": "Core performance client", | ||
@@ -35,3 +35,6 @@ "keywords": [ | ||
], | ||
"gitHead": "145aaab33c80c3efb898cf657cf3369557bcb468" | ||
"dependencies": { | ||
"@bugsnag/cuid": "^3.1.0" | ||
}, | ||
"gitHead": "343b0fdbfb62caf28fafe258735f8032f8e00b4d" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
85032
1505
1
+ Added@bugsnag/cuid@^3.1.0
+ Added@bugsnag/cuid@3.1.1(transitive)