Skip to content

Commit 57ba406

Browse files
Revert lazy init in storage
1 parent 4760132 commit 57ba406

File tree

5 files changed

+34
-45
lines changed

5 files changed

+34
-45
lines changed

src/sdkFactory/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
9999
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
100100
validateAndTrackApiKey(log, settings.core.authorizationKey);
101101
readiness.init();
102-
storage.init && storage.init();
103102
uniqueKeysTracker && uniqueKeysTracker.start();
104103
syncManager && syncManager.start();
105104
signalListener && signalListener.start();

src/storages/inRedis/RedisAdapter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const DEFAULT_OPTIONS = {
2020
const DEFAULT_LIBRARY_OPTIONS = {
2121
enableOfflineQueue: false,
2222
connectTimeout: DEFAULT_OPTIONS.connectionTimeout,
23-
lazyConnect: false // @TODO true to avoid side-effects on instantiation.
23+
lazyConnect: false
2424
};
2525

2626
interface IRedisCommand {

src/storages/pluggable/__tests__/index.spec.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ describe('PLUGGABLE STORAGE', () => {
2828
test('creates a storage instance', async () => {
2929
const storageFactory = PluggableStorage({ prefix, wrapper: wrapperMock });
3030
const storage = storageFactory(internalSdkParams);
31-
storage.init();
3231

3332
assertStorageInterface(storage); // the instance must implement the storage interface
3433
expect(wrapperMock.connect).toBeCalledTimes(1); // wrapper connect method should be called once when storage is created
@@ -75,7 +74,6 @@ describe('PLUGGABLE STORAGE', () => {
7574
test('creates a storage instance for partial consumer mode (events and impressions cache in memory)', async () => {
7675
const storageFactory = PluggableStorage({ prefix, wrapper: wrapperMock });
7776
const storage = storageFactory({ ...internalSdkParams, settings: { ...internalSdkParams.settings, mode: CONSUMER_PARTIAL_MODE } });
78-
storage.init();
7977

8078
assertStorageInterface(storage);
8179
expect(wrapperMock.connect).toBeCalledTimes(1);
@@ -104,7 +102,6 @@ describe('PLUGGABLE STORAGE', () => {
104102
// Create storage instance. Wrapper is pollute but doesn't have filter query key, so it should clear the cache
105103
await new Promise(resolve => {
106104
storage = storageFactory({ onReadyCb: resolve, settings: { ...fullSettings, mode: undefined } });
107-
storage.init();
108105
});
109106

110107
// Assert that expected caches are present
@@ -124,7 +121,6 @@ describe('PLUGGABLE STORAGE', () => {
124121
// Create storage instance. This time the wrapper has the current filter query key, so it should not clear the cache
125122
await new Promise(resolve => {
126123
storage = storageFactory({ onReadyCb: resolve, settings: { ...fullSettings, mode: undefined } });
127-
storage.init();
128124
});
129125

130126
// Assert that cache was not cleared

src/storages/pluggable/index.ts

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IPluggableStorageWrapper, IStorageAsyncFactory, IStorageFactoryParams, ITelemetryCacheAsync } from '../types';
1+
import { IPluggableStorageWrapper, IStorageAsync, IStorageAsyncFactory, IStorageFactoryParams, ITelemetryCacheAsync } from '../types';
22

33
import { KeyBuilderSS } from '../KeyBuilderSS';
44
import { SplitsCachePluggable } from './SplitsCachePluggable';
@@ -62,12 +62,11 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
6262

6363
const prefix = validatePrefix(options.prefix);
6464

65-
function PluggableStorageFactory(params: IStorageFactoryParams) {
65+
function PluggableStorageFactory(params: IStorageFactoryParams): IStorageAsync {
6666
const { onReadyCb, settings, settings: { log, mode, sync: { impressionsMode }, scheduler: { impressionsQueueSize, eventsQueueSize } } } = params;
6767
const metadata = metadataBuilder(settings);
6868
const keys = new KeyBuilderSS(prefix, metadata);
6969
const wrapper = wrapperAdapter(log, options.wrapper);
70-
let connectPromise: Promise<void>;
7170

7271
const isSyncronizer = mode === undefined; // If mode is not defined, the synchronizer is running
7372
const isPartialConsumer = mode === CONSUMER_PARTIAL_MODE;
@@ -90,6 +89,35 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
9089
new UniqueKeysCachePluggable(log, keys.buildUniqueKeysKey(), wrapper) :
9190
undefined;
9291

92+
// Connects to wrapper and emits SDK_READY event on main client
93+
const connectPromise = wrapper.connect().then(() => {
94+
if (isSyncronizer) {
95+
// In standalone or producer mode, clear storage if SDK key or feature flag filter has changed
96+
return wrapper.get(keys.buildHashKey()).then((hash) => {
97+
const currentHash = getStorageHash(settings);
98+
if (hash !== currentHash) {
99+
log.info(LOG_PREFIX + 'Storage HASH has changed (SDK key, flags filter criteria or flags spec version was modified). Clearing cache');
100+
return wrapper.getKeysByPrefix(`${keys.prefix}.`).then(storageKeys => {
101+
return Promise.all(storageKeys.map(storageKey => wrapper.del(storageKey)));
102+
}).then(() => wrapper.set(keys.buildHashKey(), currentHash));
103+
}
104+
}).then(() => {
105+
onReadyCb();
106+
});
107+
} else {
108+
// Start periodic flush of async storages if not running synchronizer (producer mode)
109+
if (impressionCountsCache && (impressionCountsCache as ImpressionCountsCachePluggable).start) (impressionCountsCache as ImpressionCountsCachePluggable).start();
110+
if (uniqueKeysCache && (uniqueKeysCache as UniqueKeysCachePluggable).start) (uniqueKeysCache as UniqueKeysCachePluggable).start();
111+
if (telemetry && (telemetry as ITelemetryCacheAsync).recordConfig) (telemetry as ITelemetryCacheAsync).recordConfig();
112+
113+
onReadyCb();
114+
}
115+
}).catch((e) => {
116+
e = e || new Error('Error connecting wrapper');
117+
onReadyCb(e);
118+
return e; // Propagate error for shared clients
119+
});
120+
93121
return {
94122
splits: new SplitsCachePluggable(log, keys, wrapper, settings.sync.__splitFiltersValidation),
95123
segments: new SegmentsCachePluggable(log, keys, wrapper),
@@ -99,39 +127,6 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
99127
telemetry,
100128
uniqueKeys: uniqueKeysCache,
101129

102-
init() {
103-
if (connectPromise) return connectPromise;
104-
105-
// Connects to wrapper and emits SDK_READY event on main client
106-
return connectPromise = wrapper.connect().then(() => {
107-
if (isSyncronizer) {
108-
// In standalone or producer mode, clear storage if SDK key or feature flag filter has changed
109-
return wrapper.get(keys.buildHashKey()).then((hash) => {
110-
const currentHash = getStorageHash(settings);
111-
if (hash !== currentHash) {
112-
log.info(LOG_PREFIX + 'Storage HASH has changed (SDK key, flags filter criteria or flags spec version was modified). Clearing cache');
113-
return wrapper.getKeysByPrefix(`${keys.prefix}.`).then(storageKeys => {
114-
return Promise.all(storageKeys.map(storageKey => wrapper.del(storageKey)));
115-
}).then(() => wrapper.set(keys.buildHashKey(), currentHash));
116-
}
117-
}).then(() => {
118-
onReadyCb();
119-
});
120-
} else {
121-
// Start periodic flush of async storages if not running synchronizer (producer mode)
122-
if (impressionCountsCache && (impressionCountsCache as ImpressionCountsCachePluggable).start) (impressionCountsCache as ImpressionCountsCachePluggable).start();
123-
if (uniqueKeysCache && (uniqueKeysCache as UniqueKeysCachePluggable).start) (uniqueKeysCache as UniqueKeysCachePluggable).start();
124-
if (telemetry && (telemetry as ITelemetryCacheAsync).recordConfig) (telemetry as ITelemetryCacheAsync).recordConfig();
125-
126-
onReadyCb();
127-
}
128-
}).catch((e) => {
129-
e = e || new Error('Error connecting wrapper');
130-
onReadyCb(e);
131-
return e; // Propagate error for shared clients
132-
});
133-
},
134-
135130
// Stop periodic flush and disconnect the underlying storage
136131
destroy() {
137132
return Promise.all(isSyncronizer ? [] : [
@@ -141,8 +136,8 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
141136
},
142137

143138
// emits SDK_READY event on shared clients and returns a reference to the storage
144-
shared(_: string, onReadyCb: (error?: any) => void) {
145-
this.init().then(onReadyCb);
139+
shared(_, onReadyCb) {
140+
connectPromise.then(onReadyCb);
146141

147142
return {
148143
...this,

src/storages/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,6 @@ export interface IStorageBase<
460460
events: TEventsCache,
461461
telemetry?: TTelemetryCache,
462462
uniqueKeys?: TUniqueKeysCache,
463-
init?: () => void | Promise<void>,
464463
destroy(): void | Promise<void>,
465464
shared?: (matchingKey: string, onReadyCb: (error?: any) => void) => this
466465
}

0 commit comments

Comments
 (0)