@@ -14,7 +14,7 @@ export interface EdgeProvider {
14
14
15
15
export class EdgeFeatureStore implements LDFeatureStore {
16
16
private readonly _rootKey : string ;
17
- private _kvData : string | null = null ;
17
+ private _deserializedPromise : Promise < LDFeatureStoreDataStorage | null > | null = null ;
18
18
19
19
constructor (
20
20
private readonly _edgeProvider : EdgeProvider ,
@@ -30,11 +30,36 @@ export class EdgeFeatureStore implements LDFeatureStore {
30
30
* has a limit of 32 backend requests (including requests to fetch the KV data).
31
31
* https://docs.fastly.com/products/compute-resource-limits
32
32
*/
33
- private async _getKVData ( ) : Promise < string | null | undefined > {
34
- if ( ! this . _kvData ) {
35
- this . _kvData = await this . _edgeProvider . get ( this . _rootKey ) ;
33
+ private async _getKVData ( ) : Promise < LDFeatureStoreDataStorage | null > {
34
+ if ( ! this . _deserializedPromise ) {
35
+ this . _deserializedPromise = ( async ( ) : Promise < LDFeatureStoreDataStorage | null > => {
36
+ this . _logger . debug ( 'No cached data found, loading from KV store' ) ;
37
+ const kvData = await this . _edgeProvider . get ( this . _rootKey ) ;
38
+ if ( ! kvData ) {
39
+ this . _logger . debug ( 'No data found in KV store' ) ;
40
+ return null ;
41
+ }
42
+
43
+ this . _logger . debug ( 'Deserializing KV store data' ) ;
44
+ const deserialized = deserializePoll ( kvData ) ;
45
+ if ( ! deserialized ) {
46
+ this . _logger . debug ( 'Failed to deserialize KV store data' ) ;
47
+ return null ;
48
+ }
49
+
50
+ // Convert FlagsAndSegments to LDFeatureStoreDataStorage format
51
+ const deserializedData : LDFeatureStoreDataStorage = {
52
+ features : deserialized . flags ,
53
+ segments : deserialized . segments ,
54
+ } ;
55
+ this . _logger . debug ( 'Successfully cached deserialized data' ) ;
56
+
57
+ return deserializedData ;
58
+ } ) ( ) ;
59
+ } else {
60
+ this . _logger . debug ( 'Using cached deserialized data' ) ;
36
61
}
37
- return this . _kvData ;
62
+ return this . _deserializedPromise ;
38
63
}
39
64
40
65
async get (
@@ -47,23 +72,18 @@ export class EdgeFeatureStore implements LDFeatureStore {
47
72
this . _logger . debug ( `Requesting ${ dataKey } from ${ this . _rootKey } .${ kindKey } ` ) ;
48
73
49
74
try {
50
- const i = await this . _getKVData ( ) ;
75
+ const data = await this . _getKVData ( ) ;
51
76
52
- if ( ! i ) {
77
+ if ( ! data ) {
53
78
throw new Error ( `${ this . _rootKey } .${ kindKey } is not found in KV.` ) ;
54
79
}
55
80
56
- const item = deserializePoll ( i ) ;
57
- if ( ! item ) {
58
- throw new Error ( `Error deserializing ${ kindKey } ` ) ;
59
- }
60
-
61
81
switch ( namespace ) {
62
82
case 'features' :
63
- callback ( item . flags [ dataKey ] ) ;
83
+ callback ( data . features [ dataKey ] ) ;
64
84
break ;
65
85
case 'segments' :
66
- callback ( item . segments [ dataKey ] ) ;
86
+ callback ( data . segments [ dataKey ] ) ;
67
87
break ;
68
88
default :
69
89
callback ( null ) ;
@@ -79,22 +99,17 @@ export class EdgeFeatureStore implements LDFeatureStore {
79
99
const kindKey = namespace === 'features' ? 'flags' : namespace ;
80
100
this . _logger . debug ( `Requesting all from ${ this . _rootKey } .${ kindKey } ` ) ;
81
101
try {
82
- const i = await this . _getKVData ( ) ;
83
- if ( ! i ) {
102
+ const data = await this . _getKVData ( ) ;
103
+ if ( ! data ) {
84
104
throw new Error ( `${ this . _rootKey } .${ kindKey } is not found in KV.` ) ;
85
105
}
86
106
87
- const item = deserializePoll ( i ) ;
88
- if ( ! item ) {
89
- throw new Error ( `Error deserializing ${ kindKey } ` ) ;
90
- }
91
-
92
107
switch ( namespace ) {
93
108
case 'features' :
94
- callback ( item . flags ) ;
109
+ callback ( data . features ) ;
95
110
break ;
96
111
case 'segments' :
97
- callback ( item . segments ) ;
112
+ callback ( data . segments ) ;
98
113
break ;
99
114
default :
100
115
callback ( { } ) ;
@@ -106,13 +121,22 @@ export class EdgeFeatureStore implements LDFeatureStore {
106
121
}
107
122
108
123
async initialized ( callback : ( isInitialized : boolean ) => void = noop ) : Promise < void > {
109
- const config = await this . _getKVData ( ) ;
110
- const result = config !== null ;
111
- this . _logger . debug ( `Is ${ this . _rootKey } initialized? ${ result } ` ) ;
112
- callback ( result ) ;
124
+ try {
125
+ const deserialized = await this . _getKVData ( ) ;
126
+ const result = deserialized !== null ;
127
+ this . _logger . debug ( `Is ${ this . _rootKey } initialized? ${ result } ` ) ;
128
+ callback ( result ) ;
129
+ } catch ( err ) {
130
+ this . _logger . error ( err ) ;
131
+ this . _logger . debug ( `Is ${ this . _rootKey } initialized? false` ) ;
132
+ callback ( false ) ;
133
+ }
113
134
}
114
135
115
136
init ( allData : LDFeatureStoreDataStorage , callback : ( ) => void ) : void {
137
+ this . _getKVData ( ) . catch ( ( err ) => {
138
+ this . _logger . error ( err ) ;
139
+ } ) ;
116
140
callback ( ) ;
117
141
}
118
142
0 commit comments