Skip to content

Commit cba2a83

Browse files
Merge pull request #825 from splitio/add_factory_destroy_method
Add factory `destroy` method
2 parents 0591c35 + da09bce commit cba2a83

File tree

12 files changed

+366
-177
lines changed

12 files changed

+366
-177
lines changed

CHANGES.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
10.29.0 (September XX, 2024)
1+
10.29.0 (October XX, 2024)
2+
- Added `factory.destroy()` method, which invokes the `destroy` method on all SDK clients created by the factory.
23
- Updated @splitsoftware/splitio-commons package to version 1.18.0 that includes minor updates:
34
- Added support for targeting rules based on large segments for browsers.
45
- Updated some transitive dependencies for vulnerability fixes.
6+
- Bugfixing - Removed an overloaded `client` method in the `SplitIO.ISDK` interface that accepted a key and trafficType parameters. This interface corresponds to the SDK factory instance in NodeJS, which, unlike `SplitIO.IBrowserSDK` for the Browser, does not handle multiple client instances based on keys or traffic types.
57

68
10.28.0 (September 6, 2024)
79
- Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates:

package-lock.json

Lines changed: 213 additions & 82 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@splitsoftware/splitio",
3-
"version": "10.28.1-rc.1",
3+
"version": "10.28.1-rc.4",
44
"description": "Split SDK",
55
"files": [
66
"README.md",
@@ -40,7 +40,7 @@
4040
"node": ">=6"
4141
},
4242
"dependencies": {
43-
"@splitsoftware/splitio-commons": "1.17.1-rc.0",
43+
"@splitsoftware/splitio-commons": "1.17.1-rc.4",
4444
"@types/google.analytics": "0.0.40",
4545
"@types/ioredis": "^4.28.0",
4646
"bloom-filters": "^3.0.0",

src/__tests__/browserSuites/push-synchronization.spec.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ const config = {
4747
},
4848
urls: baseUrls,
4949
streamingEnabled: true,
50-
debug: true
5150
};
5251
const settings = settingsFactory(config);
5352

src/__tests__/browserSuites/readiness.spec.js

Lines changed: 21 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,7 @@ export default function (fetchMock, assert) {
209209
t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.');
210210
t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready');
211211

212-
Promise.all([
213-
client2.destroy(),
214-
client3.destroy(),
215-
client.destroy()
216-
]).then(() => { t.end(); });
217-
212+
splitio.destroy().then(() => { t.end(); });
218213
}, 10000);
219214
}, 0);
220215
});
@@ -293,12 +288,7 @@ export default function (fetchMock, assert) {
293288
t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.');
294289
t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready');
295290

296-
Promise.all([
297-
client2.destroy(),
298-
client3.destroy(),
299-
client.destroy()
300-
]).then(() => { t.end(); });
301-
291+
splitio.destroy().then(() => { t.end(); });
302292
}, 10000);
303293
}, 0);
304294
});
@@ -373,12 +363,7 @@ export default function (fetchMock, assert) {
373363
t.equal(getMembershipsHits(), 6 * CLIENTS_COUNT - 1, 'It should keep the producer synchronizing periodically..');
374364
t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready');
375365

376-
Promise.all([
377-
client2.destroy(),
378-
client3.destroy(),
379-
client.destroy()
380-
]).then(() => { t.end(); });
381-
366+
splitio.destroy().then(() => { t.end(); });
382367
}, 3000);
383368
}, 0);
384369
});
@@ -417,8 +402,8 @@ export default function (fetchMock, assert) {
417402
});
418403
const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions.
419404
const client = splitio.client();
420-
const client2 = splitio.client('nicolas2@split.io');
421-
const client3 = splitio.client('nicolas3@split.io');
405+
splitio.client('nicolas2@split.io');
406+
splitio.client('nicolas3@split.io');
422407

423408
client.once(client.Event.SDK_READY, () => {
424409
t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, as there are segments in the first splits payload.');
@@ -442,12 +427,7 @@ export default function (fetchMock, assert) {
442427
setTimeout(() => {
443428
t.equal(getMembershipsHits(), 6 * CLIENTS_COUNT, 'It should keep the producer synchronizing periodically..');
444429

445-
Promise.all([
446-
client2.destroy(),
447-
client3.destroy(),
448-
client.destroy()
449-
]).then(() => { t.end(); });
450-
430+
splitio.destroy().then(() => { t.end(); });
451431
}, 3000);
452432
}, 0);
453433
});
@@ -486,19 +466,15 @@ export default function (fetchMock, assert) {
486466
});
487467
const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions.
488468
const client = splitio.client();
489-
const client2 = splitio.client('nicolas2@split.io');
490-
const client3 = splitio.client('nicolas3@split.io');
469+
splitio.client('nicolas2@split.io');
470+
splitio.client('nicolas3@split.io');
491471

492472
client.once(client.Event.SDK_READY, () => {
493473
t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale.');
494474

495475
setTimeout(() => {
496476
t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and keep syncing afterwards.');
497-
Promise.all([
498-
client2.destroy(),
499-
client3.destroy(),
500-
client.destroy()
501-
]).then(() => { t.end(); });
477+
splitio.destroy().then(() => { t.end(); });
502478
}, 2500);
503479
});
504480
client.once(client.Event.SDK_READY_TIMED_OUT, () => {
@@ -533,19 +509,15 @@ export default function (fetchMock, assert) {
533509
});
534510
const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions.
535511
const client = splitio.client();
536-
const client2 = splitio.client('nicolas2@split.io');
537-
const client3 = splitio.client('nicolas3@split.io');
512+
splitio.client('nicolas2@split.io');
513+
splitio.client('nicolas3@split.io');
538514

539515
client.once(client.Event.SDK_READY, () => {
540516
t.ok(Date.now() - start < 50, 'It should be ready quickly, since it had no segments and update has no segments either.');
541517

542518
setTimeout(() => {
543519
t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt but stopped syncing afterwards');
544-
Promise.all([
545-
client2.destroy(),
546-
client3.destroy(),
547-
client.destroy()
548-
]).then(() => { t.end(); });
520+
splitio.destroy().then(() => { t.end(); });
549521
}, 4500);
550522
});
551523
client.once(client.Event.SDK_READY_TIMED_OUT, () => {
@@ -584,19 +556,15 @@ export default function (fetchMock, assert) {
584556
});
585557
const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions.
586558
const client = splitio.client();
587-
const client2 = splitio.client('nicolas2@split.io');
588-
const client3 = splitio.client('nicolas3@split.io');
559+
splitio.client('nicolas2@split.io');
560+
splitio.client('nicolas3@split.io');
589561

590562
client.once(client.Event.SDK_READY, () => {
591563
const delay = Date.now() - start;
592564
t.ok(delay >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale.');
593565
setTimeout(() => {
594566
t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt but stopped syncing afterwards');
595-
Promise.all([
596-
client2.destroy(),
597-
client3.destroy(),
598-
client.destroy()
599-
]).then(() => { t.end(); });
567+
splitio.destroy().then(() => { t.end(); });
600568
}, 3000);
601569
});
602570
client.once(client.Event.SDK_READY_TIMED_OUT, () => {
@@ -631,19 +599,15 @@ export default function (fetchMock, assert) {
631599
});
632600
const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions.
633601
const client = splitio.client();
634-
const client2 = splitio.client('nicolas2@split.io');
635-
const client3 = splitio.client('nicolas3@split.io');
602+
splitio.client('nicolas2@split.io');
603+
splitio.client('nicolas3@split.io');
636604

637605
client.once(client.Event.SDK_READY, () => {
638606
t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale and we had segments even though the update has nothing.');
639607

640608
setTimeout(() => {
641609
t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and kept syncing afterwards');
642-
Promise.all([
643-
client2.destroy(),
644-
client3.destroy(),
645-
client.destroy()
646-
]).then(() => { t.end(); });
610+
splitio.destroy().then(() => { t.end(); });
647611
}, 3000);
648612
});
649613
client.once(client.Event.SDK_READY_TIMED_OUT, () => {
@@ -681,19 +645,15 @@ export default function (fetchMock, assert) {
681645
});
682646
const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions.
683647
const client = splitio.client();
684-
const client2 = splitio.client('nicolas2@split.io');
685-
const client3 = splitio.client('nicolas3@split.io');
648+
splitio.client('nicolas2@split.io');
649+
splitio.client('nicolas3@split.io');
686650

687651
client.once(client.Event.SDK_READY, () => {
688652
t.ok(Date.now() - start < 50, 'It should be ready without waiting for memberships, since when it downloads changes it will have no more use for them.');
689653

690654
setTimeout(() => {
691655
t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and stopped syncing afterwards');
692-
Promise.all([
693-
client2.destroy(),
694-
client3.destroy(),
695-
client.destroy()
696-
]).then(() => { t.end(); });
656+
splitio.destroy().then(() => { t.end(); });
697657
}, 3000);
698658
});
699659
client.once(client.Event.SDK_READY_TIMED_OUT, () => {

src/__tests__/browserSuites/ready-promise.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ export default function readyPromiseAssertions(fetchMock, assert) {
561561
});
562562
}, 0);
563563
});
564-
}, fromSecondsToMillis(0.2));
564+
}, fromSecondsToMillis(0.25));
565565

566566
}, 'Validate that warning messages are properly sent');
567567

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { SplitFactory as SplitFactorySS } from '../../factory/node';
2+
import { SplitFactory as SplitFactoryCS } from '../../factory/browser';
3+
4+
// Tests should finish without dangling timers or requests
5+
export default function (settings, fetchMock, t) {
6+
7+
t.test('Server-side', async (assert) => {
8+
let splitio;
9+
10+
for (let i = 0; i < 100; i++) {
11+
splitio = SplitFactorySS({
12+
core: {
13+
authorizationKey: 'fake-token-' + i,
14+
},
15+
urls: {
16+
sdk: 'https://not-called/api',
17+
events: 'https://not-called/api',
18+
auth: 'https://not-called/api',
19+
}
20+
}, (modules) => {
21+
modules.lazyInit = true;
22+
});
23+
24+
const manager = splitio.manager();
25+
assert.deepEqual(manager.names(), [], 'We should not have done any request yet');
26+
27+
const client = splitio.client();
28+
assert.equal(client.getTreatment('user-1', 'split_test'), 'control', 'We should get control');
29+
assert.equal(client.track('user-1', 'user', 'my_event'), true, 'We should track the event');
30+
}
31+
32+
fetchMock.getOnce('https://not-called/api/splitChanges?s=1.1&since=-1', { status: 200, body: { splits: [], since: -1, till: 1457552620999 } });
33+
fetchMock.getOnce('https://not-called/api/splitChanges?s=1.1&since=1457552620999', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } });
34+
fetchMock.postOnce('https://not-called/api/testImpressions/bulk', 200);
35+
fetchMock.postOnce('https://not-called/api/events/bulk', 200);
36+
37+
splitio.init();
38+
await splitio.client().ready();
39+
assert.true(splitio.client().__getStatus().isReady, 'Split SDK is ready');
40+
await splitio.destroy();
41+
42+
assert.end();
43+
});
44+
45+
t.test('Client-side', async (assert) => {
46+
let splitio;
47+
48+
for (let i = 0; i < 100; i++) {
49+
splitio = SplitFactoryCS({
50+
core: {
51+
authorizationKey: 'fake-token-' + i,
52+
key: 'user-' + i,
53+
},
54+
urls: {
55+
sdk: 'https://not-called/api',
56+
events: 'https://not-called/api',
57+
auth: 'https://not-called/api',
58+
}
59+
}, (modules) => {
60+
modules.lazyInit = true;
61+
});
62+
63+
const manager = splitio.manager();
64+
assert.deepEqual(manager.names(), [], 'We should not have done any request yet');
65+
66+
const client = splitio.client();
67+
assert.equal(client.getTreatment('split_test'), 'control', 'We should get control');
68+
assert.equal(client.track('user', 'my_event'), true, 'We should track the event');
69+
70+
const otherClient = splitio.client('other-user');
71+
assert.equal(otherClient.getTreatment('split_test'), 'control', 'We should get control');
72+
assert.equal(otherClient.track('user', 'my_event'), true, 'We should track the event');
73+
}
74+
75+
fetchMock.getOnce('https://not-called/api/splitChanges?s=1.2&since=-1', { status: 200, body: { splits: [], since: -1, till: 1457552620999 } });
76+
fetchMock.getOnce('https://not-called/api/splitChanges?s=1.2&since=1457552620999', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } });
77+
fetchMock.getOnce('https://not-called/api/memberships/user-99', { status: 200, body: {} });
78+
fetchMock.getOnce('https://not-called/api/memberships/other-user', { status: 200, body: {} });
79+
fetchMock.postOnce('https://not-called/api/testImpressions/bulk', 200);
80+
fetchMock.postOnce('https://not-called/api/events/bulk', 200);
81+
82+
splitio.init();
83+
await splitio.client().ready();
84+
assert.true(splitio.client().__getStatus().isReady, 'Split SDK is ready');
85+
await splitio.destroy();
86+
87+
assert.end();
88+
});
89+
}

src/__tests__/nodeSuites/readiness.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default function (fetchMock, assert) {
4949
try {
5050
await client.ready();
5151
} catch (e) {
52-
await client.destroy();
52+
await splitio.destroy();
5353
t.end();
5454
}
5555
});

src/__tests__/online/node.spec.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import fetchMock from '../testUtils/nodeFetchMock';
33
import { url } from '../testUtils';
44
import { settingsFactory } from '../../settings/node';
55

6+
import splitChangesMock1 from '../mocks/splitchanges.since.-1.json';
7+
import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json';
8+
69
import evaluationsSuite from '../nodeSuites/evaluations.spec';
710
import evaluationsSemverSuite from '../nodeSuites/evaluations-semver.spec';
811
import eventsSuite from '../nodeSuites/events.spec';
@@ -18,10 +21,8 @@ import ipAddressesSettingDebug from '../nodeSuites/ip-addresses-setting.debug.sp
1821
import readinessSuite from '../nodeSuites/readiness.spec';
1922
import readyPromiseSuite from '../nodeSuites/ready-promise.spec';
2023
import { fetchSpecificSplits, fetchSpecificSplitsForFlagSets } from '../nodeSuites/fetch-specific-splits.spec';
21-
22-
import splitChangesMock1 from '../mocks/splitchanges.since.-1.json';
23-
import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json';
2424
import flagSets from '../nodeSuites/flag-sets.spec';
25+
import lazyInitSuite from '../nodeSuites/lazy-init.spec';
2526

2627
const config = {
2728
core: {
@@ -94,5 +95,7 @@ tape('## Node JS - E2E CI Tests ##', async function (assert) {
9495
/* Validate flag sets */
9596
assert.test('E2E / Flag sets', flagSets.bind(null, fetchMock));
9697

98+
assert.test('E2E / SplitFactory with lazy init', lazyInitSuite.bind(null, settings, fetchMock));
99+
97100
assert.end();
98101
});

src/settings/defaults/version.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const packageVersion = '10.28.1-rc.1';
1+
export const packageVersion = '10.28.1-rc.4';

0 commit comments

Comments
 (0)