Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
e6064ec
remove old telemetry modules
EmilianoSanchez Jan 18, 2022
a8413da
remove old telemetry cache tests
EmilianoSanchez Jan 19, 2022
7cd5171
Merge pull request #70 from splitio/telemetry_remove_old
EmilianoSanchez Jan 19, 2022
093c49f
implementation and UTs
EmilianoSanchez Jan 25, 2022
6ff0ad8
fixed ut utils
EmilianoSanchez Jan 25, 2022
7260708
Merge pull request #74 from splitio/telemetry_inmemory_storage
EmilianoSanchez Jan 27, 2022
df3d1d2
Merge branch 'development' into telemetry_baseline
EmilianoSanchez Apr 12, 2022
f61e083
fixed latency buckets
EmilianoSanchez Apr 12, 2022
4f5bd22
updated unit tests
EmilianoSanchez Apr 12, 2022
fe1c54d
implement telemetry cache for redis and pluggable storage
EmilianoSanchez Apr 13, 2022
ba6a24c
promise rejections must be handled
EmilianoSanchez Apr 13, 2022
8beaf44
implementation
EmilianoSanchez Apr 18, 2022
d990c2b
unit tests
EmilianoSanchez Apr 18, 2022
aaa58cc
using constants
EmilianoSanchez Apr 19, 2022
42be2f4
Merge pull request #99 from splitio/fix_latency_buckets
EmilianoSanchez Apr 21, 2022
77cfc4d
implementation
EmilianoSanchez Apr 21, 2022
3e63eef
fixes on tests
EmilianoSanchez Apr 21, 2022
00b6fd5
Merge branch 'telemetry_track_stat_evaluation' into telemetry_track_s…
EmilianoSanchez Apr 21, 2022
c701c67
Merge branch 'development' into telemetry_baseline
EmilianoSanchez Apr 25, 2022
a088b8c
added telemetryRefreshRate config param validation
EmilianoSanchez Apr 25, 2022
ac6b8e8
update: don't call recordLatency if calling recordException
EmilianoSanchez Apr 25, 2022
837101a
record latency for track method
EmilianoSanchez Apr 25, 2022
2f4ac69
recordImpressionStats and recordEventStats
EmilianoSanchez Apr 25, 2022
18eee89
recordSuccessfulSync
EmilianoSanchez Apr 25, 2022
617d5c1
recordSessionLength, recordAuthRejections, and recordTokenRefreshes
EmilianoSanchez Apr 26, 2022
504e065
recordStreamingEvents
EmilianoSanchez Apr 26, 2022
1670fd5
polishing to reuse code
EmilianoSanchez Apr 26, 2022
c7b9ddb
simplify interfaces of factory internal components
EmilianoSanchez Apr 27, 2022
5dd0626
Merge branch 'telemetry_track_stat_evaluation' into telemetry_track_s…
EmilianoSanchez Apr 27, 2022
aefddbf
polishing
EmilianoSanchez Apr 27, 2022
8134216
Merge branch 'telemetry_track_stat_evaluation' into telemetry_track_s…
EmilianoSanchez Apr 27, 2022
a8c8153
Merge branch 'telemetry_track_stat_runtime_http' into telemetry_track…
EmilianoSanchez Apr 27, 2022
6aaef8b
updated unit tests
EmilianoSanchez Apr 27, 2022
31f630b
update comment
EmilianoSanchez Apr 27, 2022
eb8fe3c
Merge pull request #100 from splitio/telemetry_cache_async
EmilianoSanchez Apr 27, 2022
f591152
Merge pull request #105 from splitio/telemetry_track_stat_evaluation
EmilianoSanchez Apr 27, 2022
a0fc971
Merge pull request #110 from splitio/telemetry_track_stat_runtime_http
EmilianoSanchez Apr 27, 2022
16cbea6
Merge branch 'telemetry_baseline' into telemetry_config_param
EmilianoSanchez Apr 27, 2022
c129225
refactor method signature of splitHttpClient
EmilianoSanchez Apr 28, 2022
7b68cd2
comments
EmilianoSanchez Apr 28, 2022
d4a73a5
update storages and add method for telemetry
EmilianoSanchez Apr 28, 2022
bb99a24
telemetry submitter
EmilianoSanchez Apr 28, 2022
654a341
removing trailing comma
EmilianoSanchez Apr 28, 2022
7142871
Merge pull request #108 from splitio/telemetry_track_stat_runtime
EmilianoSanchez Apr 28, 2022
2bd635b
Merge branch 'telemetry_baseline' into telemetry_config_param
EmilianoSanchez Apr 28, 2022
c8d31ed
Merge branch 'telemetry_config_param' into telemetry_storage_updates
EmilianoSanchez Apr 28, 2022
718d453
Merge branch 'telemetry_storage_updates' into telemetry_submitter
EmilianoSanchez Apr 28, 2022
4bf45c6
track telemetry init stats, and submit metrics/config
EmilianoSanchez Apr 28, 2022
bf7bd71
Merge branch 'telemetry_track_init' into telemetry_polishing
EmilianoSanchez Apr 28, 2022
a6193f3
refactor submitters
EmilianoSanchez Apr 28, 2022
84a936e
added first push window to telemetry submitter
EmilianoSanchez Apr 29, 2022
7d2eb6a
Merge branch 'telemetry_submitter' into telemetry_track_init
EmilianoSanchez Apr 29, 2022
1bb65ce
unit test
EmilianoSanchez Apr 29, 2022
4180a11
validate min value for telemetryRefreshRate
EmilianoSanchez Apr 29, 2022
77cfe02
unit test
EmilianoSanchez Apr 29, 2022
80469e9
update defaults and mins of impressionsRefreshRate depending on impre…
EmilianoSanchez Apr 29, 2022
6210ded
Update src/logger/messages/error.ts
EmilianoSanchez May 2, 2022
aa8b830
fixing small nits
EmilianoSanchez May 2, 2022
fbd91c3
Merge pull request #109 from splitio/telemetry_config_param
EmilianoSanchez May 2, 2022
f521eed
Merge pull request #111 from splitio/telemetry_storage_updates
EmilianoSanchez May 2, 2022
8421f4c
Merge branch 'telemetry_baseline' into telemetry_submitter
EmilianoSanchez May 2, 2022
cf9e073
Merge branch 'telemetry_submitter' into telemetry_track_init
EmilianoSanchez May 2, 2022
5591903
fixing leak in unit test
EmilianoSanchez May 2, 2022
ae5bc03
implementation
EmilianoSanchez May 2, 2022
d9ac8e4
no track telemetry in localhost mode
EmilianoSanchez May 2, 2022
2abf9bc
interface polishing
EmilianoSanchez May 3, 2022
1fa6ba1
Merge pull request #112 from splitio/telemetry_submitter
EmilianoSanchez May 3, 2022
858e072
Merge branch 'telemetry_baseline' into telemetry_track_init
EmilianoSanchez May 3, 2022
6e017bd
fix unit test
EmilianoSanchez May 3, 2022
8d8dad9
updated some utils functions
EmilianoSanchez May 4, 2022
efe7af8
comments regarding flushing telemetry on browser listener
EmilianoSanchez May 4, 2022
b611e3b
Merge pull request #113 from splitio/telemetry_track_init
EmilianoSanchez May 4, 2022
d620c4a
Merge branch 'telemetry_baseline' into telemetry_client_side_sample_rate
EmilianoSanchez May 4, 2022
865d85e
Merge branch 'telemetry_client_side_sample_rate' into telemetry_polis…
EmilianoSanchez May 4, 2022
7c12d3c
fix interface
EmilianoSanchez May 4, 2022
381e21c
fix interface
EmilianoSanchez May 4, 2022
23ff607
fix issue with checkAllSegmentsExist in client-side
EmilianoSanchez May 4, 2022
62cfe96
Merge branch 'telemetry_client_side_sample_rate' into telemetry_polis…
EmilianoSanchez May 4, 2022
83b2121
fix unit test
EmilianoSanchez May 4, 2022
3c192b9
Merge branch 'telemetry_client_side_sample_rate' into telemetry_polis…
EmilianoSanchez May 4, 2022
0fc8fee
update unit test to avoid flakiness
EmilianoSanchez May 4, 2022
1b58c64
Merge pull request #115 from splitio/telemetry_client_side_sample_rate
EmilianoSanchez May 4, 2022
314c80c
Merge pull request #116 from splitio/telemetry_polishing
EmilianoSanchez May 5, 2022
7d210c9
Merge pull request #114 from splitio/impressions_refresh_rate_default…
EmilianoSanchez May 5, 2022
fc3cdc5
updated telemetry default URL. using DEBUG log level for telemetry re…
EmilianoSanchez May 5, 2022
1ee5ca9
updated logic to handle internalReadyCbCount
EmilianoSanchez May 5, 2022
ca7a378
updated browser listener to post telemetry stats to beacon endpoint
EmilianoSanchez May 9, 2022
8735a39
Merge branch 'telemetry_browser_listener' into telemetry_polishing
EmilianoSanchez May 9, 2022
c835199
Merge pull request #118 from splitio/telemetry_browser_listener
EmilianoSanchez May 11, 2022
5b6f2eb
rc
EmilianoSanchez May 11, 2022
15f55b5
add userConsent telemetry property
EmilianoSanchez May 12, 2022
c3e0f9d
synchronize config for consumer mode
EmilianoSanchez May 12, 2022
aea7810
recordCondig method
EmilianoSanchez May 16, 2022
96ee3d4
update telemetry.init value
EmilianoSanchez May 16, 2022
d295dc4
fix issue with hset
EmilianoSanchez May 16, 2022
ab9733b
update ci
EmilianoSanchez May 16, 2022
429bb96
Merge pull request #117 from splitio/telemetry_polishing
EmilianoSanchez May 17, 2022
030ef82
review feedback
EmilianoSanchez May 17, 2022
dd09862
Merge pull request #119 from splitio/telemetry_track_init
EmilianoSanchez May 17, 2022
f53c5f3
remove unused timeTracker
EmilianoSanchez May 19, 2022
1e39aca
mySegments refresh rate
EmilianoSanchez May 20, 2022
c599a8e
prepare stable release
EmilianoSanchez May 20, 2022
32fc9c3
Merge pull request #122 from splitio/telemetry_polishing
EmilianoSanchez May 20, 2022
6fe8511
update release date
EmilianoSanchez May 20, 2022
184f3c1
removed minimum impressionsRefreshRate
EmilianoSanchez May 23, 2022
5e5665a
stable version
EmilianoSanchez May 24, 2022
72fdf84
additional unit test
EmilianoSanchez May 24, 2022
0b7d4bb
fix unit test
EmilianoSanchez May 24, 2022
daf5cd8
Merge pull request #123 from splitio/telemetry_polishing
EmilianoSanchez May 24, 2022
1d2f10b
Merge pull request #98 from splitio/telemetry_baseline
EmilianoSanchez May 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ on:
- '*'
pull_request:
branches:
- '*'
- main
- development

jobs:
build:
Expand Down
5 changes: 5 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
1.4.0 (May 24, 2022)
- Added `scheduler.telemetryRefreshRate` property to SDK configuration, and deprecated `scheduler.metricsRefreshRate` property.
- Updated SDK telemetry storage, metrics and updater to be more effective and send less often.
- Bugfixing - Updated default values for `scheduler.impressionsRefreshRate` config parameter: 300s for OPTIMIZED impression mode and 60s for DEBUG impression mode.

1.3.1 (April 19, 2022)
- Bugfixing - Added peer dependencies to avoid issues when requiring some third-party dependencies used by modules of the package (Related to issue https://github.com/splitio/javascript-client/issues/662).
- Bugfixing - Updated `ready` method to rejects the promise with an Error object instead of a string value (Related to issue https://github.com/splitio/javascript-client/issues/654).
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@splitsoftware/splitio-commons",
"version": "1.3.1",
"version": "1.4.0",
"description": "Split Javascript SDK common components",
"main": "cjs/index.js",
"module": "esm/index.js",
Expand Down
14 changes: 14 additions & 0 deletions src/__tests__/testUtils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const DEFAULT_ERROR_MARGIN = 50; // 0.05 secs if numbers are timestamps in milliseconds

/**
* Assert if an `actual` and `expected` numeric values are nearly equal.
*
* @param {number} actual actual time lapse in millis
* @param {number} expected expected time lapse in millis
* @param {number} epsilon error margin in millis
* @returns {boolean} whether the absolute difference is minor to epsilon value or not
*/
export function nearlyEqual(actual: number, expected: number, epsilon = DEFAULT_ERROR_MARGIN) {
const diff = Math.abs(actual - expected);
return diff <= epsilon;
}
2 changes: 1 addition & 1 deletion src/consent/sdkUserConsent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function createUserConsentAPI(params: ISdkFactoryContext) {
setStatus(consent: unknown) {
// validate input param
if (!isBoolean(consent)) {
log.warn(ERROR_NOT_BOOLEAN, ['setUserConsent']);
log.warn(ERROR_NOT_BOOLEAN, ['UserConsent.setStatus']);
return false;
}

Expand Down
29 changes: 22 additions & 7 deletions src/listeners/__tests__/browser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ import { IEventsCacheSync, IImpressionCountsCacheSync, IImpressionsCacheSync, IS
import { ISplitApi } from '../../services/types';
import { fullSettings } from '../../utils/settingsValidation/__tests__/settings.mocks';

jest.mock('../../sync/submitters/telemetrySubmitter', () => {
return {
telemetryCacheStatsAdapter: () => {
return {
isEmpty: () => false,
clear: () => { },
state: () => ({}),
};
}
};
});

/* Mocks start */

const fakeImpression = {
Expand All @@ -26,6 +38,7 @@ const fakeImpressionCounts = {
'someFeature::0': 1
};

// Storage with impressionsCount and telemetry cache
const fakeStorageOptimized = { // @ts-expect-error
impressions: {
isEmpty: jest.fn(),
Expand All @@ -48,6 +61,7 @@ const fakeStorageOptimized = { // @ts-expect-error
return fakeImpressionCounts;
}
} as IImpressionCountsCacheSync,
telemetry: {}
};

const fakeStorageDebug = {
Expand All @@ -59,7 +73,8 @@ const fakeStorageDebug = {
const fakeSplitApi = {
postTestImpressionsBulk: jest.fn(() => Promise.resolve()),
postEventsBulk: jest.fn(() => Promise.resolve()),
postTestImpressionsCount: jest.fn(() => Promise.resolve())
postTestImpressionsCount: jest.fn(() => Promise.resolve()),
postMetricsUsage: jest.fn(() => Promise.resolve()),
} as ISplitApi;

const UNLOAD_DOM_EVENT = 'unload';
Expand Down Expand Up @@ -131,7 +146,7 @@ test('Browser JS listener / consumer mode', () => {
expect((global.window.removeEventListener as jest.Mock).mock.calls).toEqual([[UNLOAD_DOM_EVENT, listener.flushData]]);
});

test('Browser JS listener / standalone mode / Impressions optimized mode', () => {
test('Browser JS listener / standalone mode / Impressions optimized mode with telemetry', () => {
const syncManagerMock = {};

// @ts-expect-error
Expand All @@ -144,8 +159,8 @@ test('Browser JS listener / standalone mode / Impressions optimized mode', () =>

triggerUnloadEvent();

// Unload event was triggered. Thus sendBeacon method should have been called three times.
expect(global.window.navigator.sendBeacon).toBeCalledTimes(3);
// Unload event was triggered. Thus sendBeacon method should have been called four times.
expect(global.window.navigator.sendBeacon).toBeCalledTimes(4);

// Http post services should have not been called
expect(fakeSplitApi.postTestImpressionsBulk).not.toBeCalled();
Expand Down Expand Up @@ -195,7 +210,7 @@ test('Browser JS listener / standalone mode / Impressions debug mode', () => {
});

test('Browser JS listener / standalone mode / Impressions debug mode without sendBeacon API', () => {
// remove sendBeacon API
// remove sendBeacon API temporally
const sendBeacon = global.navigator.sendBeacon; // @ts-expect-error
global.navigator.sendBeacon = undefined;
const syncManagerMockWithoutPushManager = {};
Expand Down Expand Up @@ -254,8 +269,8 @@ test('Browser JS listener / standalone mode / user consent status', () => {
settings.userConsent = undefined;
triggerUnloadEvent();

// Unload event was triggered when user consent was granted and undefined. Thus sendBeacon should be called 6 times (3 times per event in optimized mode).
expect(global.window.navigator.sendBeacon).toBeCalledTimes(6);
// Unload event was triggered when user consent was granted and undefined. Thus sendBeacon should be called 8 times (4 times per event in optimized mode with telemetry).
expect(global.window.navigator.sendBeacon).toBeCalledTimes(8);

listener.stop();
});
10 changes: 8 additions & 2 deletions src/listeners/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// @TODO eventually migrate to JS-Browser-SDK package.
import { ISignalListener } from './types';
import { IRecorderCacheProducerSync, IStorageSync } from '../storages/types';
import { fromImpressionsCollector } from '../sync/submitters/impressionsSyncTask';
import { fromImpressionCountsCollector } from '../sync/submitters/impressionCountsSyncTask';
import { fromImpressionsCollector } from '../sync/submitters/impressionsSubmitter';
import { fromImpressionCountsCollector } from '../sync/submitters/impressionCountsSubmitter';
import { IResponse, ISplitApi } from '../services/types';
import { ImpressionDTO, ISettings } from '../types';
import { ImpressionsPayload } from '../sync/submitters/types';
Expand All @@ -12,6 +12,7 @@ import { objectAssign } from '../utils/lang/objectAssign';
import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
import { ISyncManager } from '../sync/types';
import { isConsentGranted } from '../consent';
import { telemetryCacheStatsAdapter } from '../sync/submitters/telemetrySubmitter';

// 'unload' event is used instead of 'beforeunload', since 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
const UNLOAD_DOM_EVENT = 'unload';
Expand Down Expand Up @@ -77,6 +78,11 @@ export class BrowserSignalListener implements ISignalListener {
this._flushData(eventsUrl + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
this._flushData(eventsUrl + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
if (this.storage.impressionCounts) this._flushData(eventsUrl + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector);
if (this.storage.telemetry) {
const telemetryUrl = this.settings.urls.telemetry;
const telemetryCacheAdapter = telemetryCacheStatsAdapter(this.storage.telemetry, this.storage.splits, this.storage.segments);
this._flushData(telemetryUrl + '/v1/metrics/usage/beacon', telemetryCacheAdapter, this.serviceApi.postMetricsUsage);
}
}

// Close streaming connection
Expand Down
1 change: 1 addition & 0 deletions src/logger/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export const ERROR_HTTP = 322;
export const ERROR_LOCALHOST_MODULE_REQUIRED = 323;
export const ERROR_STORAGE_INVALID = 324;
export const ERROR_NOT_BOOLEAN = 325;
export const ERROR_MIN_CONFIG_PARAM = 326;

// Log prefixes (a.k.a. tags or categories)
export const LOG_PREFIX_SETTINGS = 'settings';
Expand Down
3 changes: 2 additions & 1 deletion src/logger/messages/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ export const codesError: [number, string][] = [
// initialization / settings validation
[c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
[c.ERROR_LOCALHOST_MODULE_REQUIRED, c.LOG_PREFIX_SETTINGS + ': an invalid value was received for "sync.localhostMode" config. A valid entity should be provided for localhost mode.'],
[c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS+': The provided storage is invalid.%s Fallbacking into default MEMORY storage'],
[c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS+': the provided storage is invalid.%s Falling back into default MEMORY storage'],
[c.ERROR_MIN_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': the provided "%s" config param is lower than allowed. Setting to the minimum value %s seconds'],
];
6 changes: 3 additions & 3 deletions src/logger/messages/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export const codesInfo: [number, string][] = codesWarn.concat([
[c.NEW_FACTORY, 'New Split SDK instance created.'],
[c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
[c.USER_CONSENT_UPDATED, 'setUserConsent: consent status changed from %s to %s.'],
[c.USER_CONSENT_NOT_UPDATED, 'setUserConsent: call had no effect because it was the current consent status (%s).'],
[c.USER_CONSENT_UPDATED, 'UserConsent: consent status changed from %s to %s.'],
[c.USER_CONSENT_NOT_UPDATED, 'UserConsent: call had no effect because it was the current consent status (%s).'],
[c.USER_CONSENT_INITIAL, 'Starting the SDK with %s user consent. No data will be sent.'],

// synchronizer
Expand All @@ -24,7 +24,7 @@ export const codesInfo: [number, string][] = codesWarn.concat([
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of splits #%s. Reason: %s'],
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and reseting timer.'],
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s %s.'],
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
[c.STREAMING_CONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Connecting streaming.'],
Expand Down
4 changes: 2 additions & 2 deletions src/logger/messages/warn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export const codesWarn: [number, string][] = codesError.concat([
[c.STREAMING_PARSING_ERROR_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE error notification: %s'],
[c.STREAMING_PARSING_MESSAGE_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE message notification: %s'],
[c.STREAMING_FALLBACK, c.LOG_PREFIX_SYNC_STREAMING + 'Falling back to polling mode. Reason: %s'],
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Droping %s %s after retry. Reason: %s.'],
[c.SUBMITTERS_PUSH_RETRY, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Failed to push %s %s, keeping data to retry on next iteration. Reason: %s.'],
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Droping %s after retry. Reason: %s.'],
[c.SUBMITTERS_PUSH_RETRY, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Failed to push %s, keeping data to retry on next iteration. Reason: %s.'],
// client status
[c.CLIENT_NOT_READY, '%s: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method.'],
[c.CLIENT_NO_LISTENER, 'No listeners for SDK Readiness detected. Incorrect control treatments could have been logged if you called getTreatment/s while the SDK was not yet ready.'],
Expand Down
3 changes: 2 additions & 1 deletion src/readiness/__tests__/sdkReadinessManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ describe('SDK Readiness Manager - Event emitter', () => {

test('The event callbacks should work as expected - SDK_READY emits with expected internal callbacks', () => {
// the sdkReadinessManager expects more than one SDK_READY callback to not log the "No listeners" warning
const sdkReadinessManager = sdkReadinessManagerFactory(loggerMock, EventEmitterMock, undefined /* default readyTimeout */, 1 /* internalReadyCbCount */);
const sdkReadinessManager = sdkReadinessManagerFactory(loggerMock, EventEmitterMock);
sdkReadinessManager.incInternalReadyCbCount();
const gateMock = sdkReadinessManager.readinessManager.gate;

// Get the callbacks
Expand Down
12 changes: 7 additions & 5 deletions src/readiness/sdkReadinessManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,16 @@ const REMOVE_LISTENER_EVENT = 'removeListener';
* It also updates logs related warnings and errors.
*
* @param readyTimeout time in millis to emit SDK_READY_TIME_OUT event
* @param internalReadyCbCount offset value of SDK_READY listeners that are added/removed internally
* by the SDK. It is required to properly log the warning 'No listeners for SDK Readiness detected'
* @param readinessManager optional readinessManager to use. only used internally for `shared` method
*/
export function sdkReadinessManagerFactory(
log: ILogger,
EventEmitter: new () => IEventEmitter,
readyTimeout = 0,
internalReadyCbCount = 0,
readinessManager = readinessManagerFactory(EventEmitter, readyTimeout)): ISdkReadinessManager {

/** Ready callback warning */
let internalReadyCbCount = 0;
let readyCbCount = 0;
readinessManager.gate.on(REMOVE_LISTENER_EVENT, (event: any) => {
if (event === SDK_READY) readyCbCount--;
Expand Down Expand Up @@ -74,8 +72,12 @@ export function sdkReadinessManagerFactory(
return {
readinessManager,

shared(readyTimeout = 0, internalReadyCbCount = 0) {
return sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, internalReadyCbCount, readinessManager.shared(readyTimeout));
shared(readyTimeout = 0) {
return sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, readinessManager.shared(readyTimeout));
},

incInternalReadyCbCount() {
internalReadyCbCount++;
},

sdkStatus: objectAssign(
Expand Down
8 changes: 7 additions & 1 deletion src/readiness/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ export interface ISdkReadinessManager {
readinessManager: IReadinessManager
sdkStatus: IStatusInterface

/**
* Increment internalReadyCbCount, an offset value of SDK_READY listeners that are added/removed internally
* by the SDK. It is required to properly log the warning 'No listeners for SDK Readiness detected'
*/
incInternalReadyCbCount(): void

/** for client-side */
shared(readyTimeout?: number, internalReadyCbCount?: number): ISdkReadinessManager
shared(readyTimeout?: number): ISdkReadinessManager
}
7 changes: 5 additions & 2 deletions src/sdkClient/__tests__/sdkClientMethod.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { loggerMock } from '../../logger/__tests__/sdkLogger.mock';
import { CONSUMER_MODE, STANDALONE_MODE } from '../../utils/constants';
import { sdkClientMethodFactory } from '../sdkClientMethod';
import { assertClientApi } from './testUtils';
import { telemetryTrackerFactory } from '../../trackers/telemetryTracker';

const errorMessage = 'Shared Client not supported by the storage mechanism. Create isolated instances instead.';

Expand All @@ -12,15 +13,17 @@ const paramMocks = [
syncManager: undefined,
sdkReadinessManager: { sdkStatus: jest.fn(), readinessManager: { destroy: jest.fn() } },
signalListener: undefined,
settings: { mode: CONSUMER_MODE, log: loggerMock, core: { authorizationKey: 'api key '} }
settings: { mode: CONSUMER_MODE, log: loggerMock, core: { authorizationKey: 'api key '} },
telemetryTracker: telemetryTrackerFactory()
},
// SyncManager (i.e., Sync SDK) and Signal listener
{
storage: { destroy: jest.fn() },
syncManager: { stop: jest.fn(), flush: jest.fn(() => Promise.resolve()) },
sdkReadinessManager: { sdkStatus: jest.fn(), readinessManager: { destroy: jest.fn() } },
signalListener: { stop: jest.fn() },
settings: { mode: STANDALONE_MODE, log: loggerMock, core: { authorizationKey: 'api key '} }
settings: { mode: STANDALONE_MODE, log: loggerMock, core: { authorizationKey: 'api key '} },
telemetryTracker: telemetryTrackerFactory()
}
];

Expand Down
5 changes: 3 additions & 2 deletions src/sdkClient/__tests__/sdkClientMethodCS.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { sdkClientMethodCSFactory as sdkClientMethodCSWithTTFactory } from '../sdkClientMethodCSWithTT';
import { sdkClientMethodCSFactory } from '../sdkClientMethodCS';
import { assertClientApi } from './testUtils';

import { telemetryTrackerFactory } from '../../trackers/telemetryTracker';
import { settingsWithKey, settingsWithKeyAndTT, settingsWithKeyObject } from '../../utils/settingsValidation/__tests__/settings.mocks';

const partialStorages: { destroy: jest.Mock }[] = [];
Expand Down Expand Up @@ -44,7 +44,8 @@ const params = {
sdkReadinessManager: sdkReadinessManagerMock,
syncManager: syncManagerMock,
signalListener: { stop: jest.fn() },
settings: settingsWithKey
settings: settingsWithKey,
telemetryTracker: telemetryTrackerFactory()
};

const invalidAttributes = [
Expand Down
Loading