Skip to content

Commit 056141a

Browse files
committed
WIP
1 parent 5cf6449 commit 056141a

13 files changed

Lines changed: 182 additions & 72 deletions

src/main/java/io/split/android/client/service/executor/SplitTaskFactoryImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import io.split.android.client.storage.cipher.SplitCipher;
4949
import io.split.android.client.storage.common.SplitStorageContainer;
5050
import io.split.android.client.storage.db.SplitRoomDatabase;
51+
import io.split.android.client.storage.rbs.RuleBasedSegmentStorageProducer;
5152
import io.split.android.client.telemetry.storage.TelemetryRuntimeProducer;
5253
import io.split.android.client.telemetry.storage.TelemetryStorage;
5354

@@ -64,6 +65,7 @@ public class SplitTaskFactoryImpl implements SplitTaskFactory {
6465
private final SplitChangeProcessor mSplitChangeProcessor;
6566
private final TelemetryRuntimeProducer mTelemetryRuntimeProducer;
6667
private final List<SplitFilter> mFilters;
68+
private final RuleBasedSegmentStorageProducer mRuleBasedSegmentStorageProducer;
6769

6870
@SuppressLint("VisibleForTests")
6971
public SplitTaskFactoryImpl(@NonNull SplitClientConfig splitClientConfig,
@@ -90,6 +92,7 @@ public SplitTaskFactoryImpl(@NonNull SplitClientConfig splitClientConfig,
9092
mSplitsSyncHelper = new SplitsSyncHelper(mSplitApiFacade.getSplitFetcher(),
9193
mSplitsStorageContainer.getSplitsStorage(),
9294
mSplitChangeProcessor,
95+
mRuleBasedSegmentStorageProducer,
9396
mTelemetryRuntimeProducer,
9497
new ReconnectBackoffCounter(1, testingConfig.getCdnBackoffTime()),
9598
flagsSpecFromConfig);

src/main/java/io/split/android/client/service/splits/SplitsSyncHelper.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88
import androidx.annotation.VisibleForTesting;
99

1010
import java.util.Collections;
11+
import java.util.HashSet;
1112
import java.util.LinkedHashMap;
1213
import java.util.Map;
14+
import java.util.Set;
1315
import java.util.concurrent.TimeUnit;
1416

17+
import io.split.android.client.dtos.RuleBasedSegment;
18+
import io.split.android.client.dtos.RuleBasedSegmentChange;
1519
import io.split.android.client.dtos.SplitChange;
20+
import io.split.android.client.dtos.Status;
1621
import io.split.android.client.dtos.TargetingRulesChange;
1722
import io.split.android.client.network.SplitHttpHeadersBuilder;
1823
import io.split.android.client.service.ServiceConstants;
@@ -23,6 +28,8 @@
2328
import io.split.android.client.service.http.HttpStatus;
2429
import io.split.android.client.service.sseclient.BackoffCounter;
2530
import io.split.android.client.service.sseclient.ReconnectBackoffCounter;
31+
import io.split.android.client.storage.rbs.RuleBasedSegmentStorage;
32+
import io.split.android.client.storage.rbs.RuleBasedSegmentStorageProducer;
2633
import io.split.android.client.storage.splits.SplitsStorage;
2734
import io.split.android.client.telemetry.model.OperationType;
2835
import io.split.android.client.telemetry.storage.TelemetryRuntimeProducer;
@@ -37,18 +44,21 @@ public class SplitsSyncHelper {
3744
private final HttpFetcher<TargetingRulesChange> mSplitFetcher;
3845
private final SplitsStorage mSplitsStorage;
3946
private final SplitChangeProcessor mSplitChangeProcessor;
47+
private final RuleBasedSegmentStorageProducer mRuleBasedSegmentStorage;
4048
private final TelemetryRuntimeProducer mTelemetryRuntimeProducer;
4149
private final BackoffCounter mBackoffCounter;
4250
private final String mFlagsSpec;
4351

4452
public SplitsSyncHelper(@NonNull HttpFetcher<TargetingRulesChange> splitFetcher,
4553
@NonNull SplitsStorage splitsStorage,
4654
@NonNull SplitChangeProcessor splitChangeProcessor,
55+
@NonNull RuleBasedSegmentStorageProducer ruleBasedSegmentStorage,
4756
@NonNull TelemetryRuntimeProducer telemetryRuntimeProducer,
4857
@Nullable String flagsSpec) {
4958
this(splitFetcher,
5059
splitsStorage,
5160
splitChangeProcessor,
61+
ruleBasedSegmentStorage,
5262
telemetryRuntimeProducer,
5363
new ReconnectBackoffCounter(1, ON_DEMAND_FETCH_BACKOFF_MAX_WAIT),
5464
flagsSpec);
@@ -58,12 +68,14 @@ public SplitsSyncHelper(@NonNull HttpFetcher<TargetingRulesChange> splitFetcher,
5868
public SplitsSyncHelper(@NonNull HttpFetcher<TargetingRulesChange> splitFetcher,
5969
@NonNull SplitsStorage splitsStorage,
6070
@NonNull SplitChangeProcessor splitChangeProcessor,
71+
@NonNull RuleBasedSegmentStorageProducer ruleBasedSegmentStorage,
6172
@NonNull TelemetryRuntimeProducer telemetryRuntimeProducer,
6273
@NonNull BackoffCounter backoffCounter,
6374
@Nullable String flagsSpec) {
6475
mSplitFetcher = checkNotNull(splitFetcher);
6576
mSplitsStorage = checkNotNull(splitsStorage);
6677
mSplitChangeProcessor = checkNotNull(splitChangeProcessor);
78+
mRuleBasedSegmentStorage = checkNotNull(ruleBasedSegmentStorage);
6779
mTelemetryRuntimeProducer = checkNotNull(telemetryRuntimeProducer);
6880
mBackoffCounter = checkNotNull(backoffCounter);
6981
mFlagsSpec = flagsSpec;
@@ -155,8 +167,9 @@ private long fetchUntil(long till, boolean clearBeforeUpdate, boolean avoidCache
155167
}
156168

157169
TargetingRulesChange targetingRulesChange = fetchSplits(changeNumber, avoidCache, withCdnByPass);
158-
SplitChange splitChange = targetingRulesChange.getFeatureFlagsChange(); // TODO
159-
updateStorage(shouldClearBeforeUpdate, splitChange);
170+
SplitChange splitChange = targetingRulesChange.getFeatureFlagsChange();
171+
RuleBasedSegmentChange ruleBasedSegmentChange = targetingRulesChange.getRuleBasedSegmentsChange();
172+
updateStorage(shouldClearBeforeUpdate, splitChange, ruleBasedSegmentChange);
160173
shouldClearBeforeUpdate = false;
161174

162175
newTill = splitChange.till;
@@ -180,11 +193,27 @@ private TargetingRulesChange fetchSplits(long till, boolean avoidCache, boolean
180193
return mSplitFetcher.execute(params, getHeaders(avoidCache));
181194
}
182195

183-
private void updateStorage(boolean clearBeforeUpdate, SplitChange splitChange) {
196+
private void updateStorage(boolean clearBeforeUpdate, SplitChange splitChange, RuleBasedSegmentChange ruleBasedSegmentChange) {
184197
if (clearBeforeUpdate) {
185198
mSplitsStorage.clear();
199+
mRuleBasedSegmentStorage.clear();
186200
}
187201
mSplitsStorage.update(mSplitChangeProcessor.process(splitChange));
202+
updateRbsStorage(ruleBasedSegmentChange);
203+
}
204+
205+
private void updateRbsStorage(RuleBasedSegmentChange ruleBasedSegmentChange) {
206+
long changeNumber = ruleBasedSegmentChange.getTill();
207+
Set<RuleBasedSegment> toAdd = new HashSet<>();
208+
Set<RuleBasedSegment> toRemove = new HashSet<>();
209+
for (RuleBasedSegment segment : ruleBasedSegmentChange.getSegments()) {
210+
if (segment.getStatus() == Status.ACTIVE) {
211+
toAdd.add(segment);
212+
} else {
213+
toRemove.add(segment);
214+
}
215+
}
216+
mRuleBasedSegmentStorage.update(toAdd, toRemove, changeNumber);
188217
}
189218

190219
private void logError(String message) {

src/main/java/io/split/android/client/service/workmanager/splits/SplitsSyncWorkerTaskBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import io.split.android.client.service.splits.SplitChangeProcessor;
77
import io.split.android.client.service.splits.SplitsSyncHelper;
88
import io.split.android.client.service.splits.SplitsSyncTask;
9+
import io.split.android.client.storage.rbs.RuleBasedSegmentStorageProducer;
910
import io.split.android.client.storage.splits.SplitsStorage;
1011
import io.split.android.client.telemetry.storage.TelemetryStorage;
1112
import io.split.android.client.utils.logger.Logger;
@@ -37,12 +38,14 @@ SplitTask getTask() {
3738
try {
3839
SplitsStorage splitsStorage = mStorageProvider.provideSplitsStorage();
3940
TelemetryStorage telemetryStorage = mStorageProvider.provideTelemetryStorage();
41+
RuleBasedSegmentStorageProducer ruleBasedSegmentStorageProducer = mStorageProvider.provideRuleBasedSegmentStorage();
4042
String splitsFilterQueryString = splitsStorage.getSplitsFilterQueryString();
4143

4244
SplitsSyncHelper splitsSyncHelper = mSplitsSyncHelperProvider.provideSplitsSyncHelper(
4345
mFetcherProvider.provideFetcher(splitsFilterQueryString),
4446
splitsStorage,
4547
mSplitChangeProcessor,
48+
ruleBasedSegmentStorageProducer,
4649
telemetryStorage,
4750
mFlagsSpec);
4851

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
package io.split.android.client.service.workmanager.splits;
22

3+
import io.split.android.client.storage.cipher.SplitCipher;
4+
import io.split.android.client.storage.cipher.SplitCipherFactory;
35
import io.split.android.client.storage.db.SplitRoomDatabase;
46
import io.split.android.client.storage.db.StorageFactory;
7+
import io.split.android.client.storage.rbs.RuleBasedSegmentStorageProducer;
58
import io.split.android.client.storage.splits.SplitsStorage;
69
import io.split.android.client.telemetry.storage.TelemetryStorage;
710

811
class StorageProvider {
912

1013
private final SplitRoomDatabase mDatabase;
11-
private final String mApiKey;
12-
private final boolean mEncryptionEnabled;
1314
private final boolean mShouldRecordTelemetry;
15+
private final SplitCipher mCipher;
1416

1517
StorageProvider(SplitRoomDatabase database, String apiKey, boolean encryptionEnabled, boolean shouldRecordTelemetry) {
1618
mDatabase = database;
17-
mApiKey = apiKey;
18-
mEncryptionEnabled = encryptionEnabled;
19+
mCipher = SplitCipherFactory.create(apiKey, encryptionEnabled);
1920
mShouldRecordTelemetry = shouldRecordTelemetry;
2021
}
2122

2223
SplitsStorage provideSplitsStorage() {
23-
SplitsStorage splitsStorageForWorker = StorageFactory.getSplitsStorageForWorker(mDatabase, mApiKey, mEncryptionEnabled);
24+
SplitsStorage splitsStorageForWorker = StorageFactory.getSplitsStorage(mDatabase, mCipher);
2425
splitsStorageForWorker.loadLocal(); // call loadLocal to populate storage with DB data
2526

2627
return splitsStorageForWorker;
@@ -29,4 +30,8 @@ SplitsStorage provideSplitsStorage() {
2930
TelemetryStorage provideTelemetryStorage() {
3031
return StorageFactory.getTelemetryStorage(mShouldRecordTelemetry);
3132
}
33+
34+
RuleBasedSegmentStorageProducer provideRuleBasedSegmentStorage() {
35+
return StorageFactory.getRuleBasedSegmentStorageForWorker(mDatabase, mCipher);
36+
}
3237
}

src/main/java/io/split/android/client/service/workmanager/splits/SyncHelperProvider.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@
44
import io.split.android.client.service.http.HttpFetcher;
55
import io.split.android.client.service.splits.SplitChangeProcessor;
66
import io.split.android.client.service.splits.SplitsSyncHelper;
7+
import io.split.android.client.storage.rbs.RuleBasedSegmentStorageProducer;
78
import io.split.android.client.storage.splits.SplitsStorage;
89
import io.split.android.client.telemetry.storage.TelemetryStorage;
910

1011
class SyncHelperProvider {
1112

12-
SplitsSyncHelper provideSplitsSyncHelper(HttpFetcher<TargetingRulesChange> splitsFetcher, SplitsStorage splitsStorage,
13-
SplitChangeProcessor mSplitChangeProcessor,
13+
SplitsSyncHelper provideSplitsSyncHelper(HttpFetcher<TargetingRulesChange> splitsFetcher,
14+
SplitsStorage splitsStorage,
15+
SplitChangeProcessor splitChangeProcessor,
16+
RuleBasedSegmentStorageProducer ruleBasedSegmentStorage,
1417
TelemetryStorage telemetryStorage,
1518
String mFlagsSpec) {
1619
return new SplitsSyncHelper(splitsFetcher, splitsStorage,
17-
mSplitChangeProcessor,
20+
splitChangeProcessor,
21+
ruleBasedSegmentStorage,
1822
telemetryStorage,
1923
mFlagsSpec);
2024
}

src/main/java/io/split/android/client/storage/db/StorageFactory.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import io.split.android.client.storage.mysegments.MySegmentsStorageContainerImpl;
3232
import io.split.android.client.storage.mysegments.SqLitePersistentMySegmentsStorage;
3333
import io.split.android.client.storage.rbs.PersistentRuleBasedSegmentStorage;
34+
import io.split.android.client.storage.rbs.RuleBasedSegmentStorageImpl;
35+
import io.split.android.client.storage.rbs.RuleBasedSegmentStorageProducer;
3436
import io.split.android.client.storage.rbs.SqLitePersistentRuleBasedSegmentStorageProvider;
3537
import io.split.android.client.storage.splits.PersistentSplitsStorage;
3638
import io.split.android.client.storage.splits.SplitsStorage;
@@ -160,4 +162,11 @@ public static GeneralInfoStorage getGeneralInfoStorage(SplitRoomDatabase splitRo
160162
public static PersistentRuleBasedSegmentStorage getPersistentRuleBasedSegmentStorage(SplitRoomDatabase splitRoomDatabase, SplitCipher splitCipher, GeneralInfoStorage generalInfoStorage) {
161163
return new SqLitePersistentRuleBasedSegmentStorageProvider(splitCipher, splitRoomDatabase, generalInfoStorage).get();
162164
}
165+
166+
public static RuleBasedSegmentStorageProducer getRuleBasedSegmentStorageForWorker(SplitRoomDatabase splitRoomDatabase, SplitCipher splitCipher) {
167+
GeneralInfoStorage generalInfoStorage = new GeneralInfoStorageImpl(splitRoomDatabase.generalInfoDao());
168+
PersistentRuleBasedSegmentStorage persistentRuleBasedSegmentStorage =
169+
new SqLitePersistentRuleBasedSegmentStorageProvider(splitCipher, splitRoomDatabase, generalInfoStorage).get();
170+
return new RuleBasedSegmentStorageImpl(persistentRuleBasedSegmentStorage, null);
171+
}
163172
}
Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,5 @@
11
package io.split.android.client.storage.rbs;
22

3-
import androidx.annotation.NonNull;
4-
import androidx.annotation.Nullable;
3+
public interface RuleBasedSegmentStorage extends RuleBasedSegmentStorageConsumer, RuleBasedSegmentStorageProducer {
54

6-
import java.util.Set;
7-
8-
import io.split.android.client.dtos.RuleBasedSegment;
9-
import io.split.android.client.storage.RolloutDefinitionsCache;
10-
import io.split.android.engine.experiments.ParsedRuleBasedSegment;
11-
12-
public interface RuleBasedSegmentStorage extends RolloutDefinitionsCache {
13-
14-
@Nullable
15-
ParsedRuleBasedSegment get(String segmentName, String matchingKey);
16-
17-
boolean update(@NonNull Set<RuleBasedSegment> toAdd, @NonNull Set<RuleBasedSegment> toRemove, long changeNumber);
18-
19-
long getChangeNumber();
20-
21-
boolean contains(@NonNull Set<String> segmentNames);
225
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.split.android.client.storage.rbs;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.Nullable;
5+
6+
import java.util.Set;
7+
8+
import io.split.android.engine.experiments.ParsedRuleBasedSegment;
9+
10+
public interface RuleBasedSegmentStorageConsumer {
11+
12+
@Nullable
13+
ParsedRuleBasedSegment get(String segmentName, String matchingKey);
14+
15+
long getChangeNumber();
16+
17+
boolean contains(@NonNull Set<String> segmentNames);
18+
}

src/main/java/io/split/android/client/storage/rbs/RuleBasedSegmentStorageImpl.java

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
import androidx.annotation.Nullable;
77
import androidx.annotation.WorkerThread;
88

9-
import java.util.Map;
109
import java.util.Set;
1110
import java.util.concurrent.ConcurrentHashMap;
11+
import java.util.concurrent.atomic.AtomicLong;
1212

1313
import io.split.android.client.dtos.RuleBasedSegment;
1414
import io.split.android.engine.experiments.ParsedRuleBasedSegment;
@@ -17,15 +17,16 @@
1717
public class RuleBasedSegmentStorageImpl implements RuleBasedSegmentStorage {
1818

1919
private final ConcurrentHashMap<String, RuleBasedSegment> mInMemorySegments;
20+
@Nullable
2021
private final RuleBasedSegmentParser mParser;
21-
private final PersistentRuleBasedSegmentStorage mPersistentStorage;
22-
private volatile long mChangeNumber;
22+
private final RuleBasedSegmentStorageProducer mProducer;
23+
private final AtomicLong mChangeNumberRef;
2324

24-
public RuleBasedSegmentStorageImpl(@NonNull PersistentRuleBasedSegmentStorage persistentStorage, @NonNull RuleBasedSegmentParser parser) {
25+
public RuleBasedSegmentStorageImpl(@NonNull PersistentRuleBasedSegmentStorage persistentStorage, @Nullable RuleBasedSegmentParser parser) {
2526
mInMemorySegments = new ConcurrentHashMap<>();
2627
mParser = checkNotNull(parser);
27-
mPersistentStorage = checkNotNull(persistentStorage);
28-
mChangeNumber = -1;
28+
mChangeNumberRef = new AtomicLong(-1);
29+
mProducer = new RuleBasedSegmentStorageProducerImpl(persistentStorage, mInMemorySegments, mChangeNumberRef);
2930
}
3031

3132
@Override
@@ -40,34 +41,12 @@ public RuleBasedSegmentStorageImpl(@NonNull PersistentRuleBasedSegmentStorage pe
4041

4142
@Override
4243
public synchronized boolean update(@NonNull Set<RuleBasedSegment> toAdd, @NonNull Set<RuleBasedSegment> toRemove, long changeNumber) {
43-
boolean appliedUpdates = false;
44-
45-
if (toAdd != null) {
46-
if (!toAdd.isEmpty()) {
47-
for (RuleBasedSegment segment : toAdd) {
48-
mInMemorySegments.put(segment.getName(), segment);
49-
}
50-
51-
appliedUpdates = true;
52-
}
53-
}
54-
55-
if (toRemove != null) {
56-
if (!toRemove.isEmpty()) {
57-
for (RuleBasedSegment segment : toRemove) {
58-
mInMemorySegments.remove(segment.getName());
59-
}
60-
}
61-
}
62-
63-
mChangeNumber = changeNumber;
64-
65-
return appliedUpdates;
44+
return mProducer.update(toAdd, toRemove, changeNumber);
6645
}
6746

6847
@Override
6948
public long getChangeNumber() {
70-
return mChangeNumber;
49+
return mChangeNumberRef.get();
7150
}
7251

7352
@Override
@@ -87,17 +66,12 @@ public boolean contains(@NonNull Set<String> segmentNames) {
8766
@WorkerThread
8867
@Override
8968
public synchronized void loadLocal() {
90-
RuleBasedSegmentSnapshot snapshot = mPersistentStorage.getSnapshot();
91-
Map<String, RuleBasedSegment> segments = snapshot.getSegments();
92-
mChangeNumber = snapshot.getChangeNumber();
93-
mInMemorySegments.putAll(segments);
69+
mProducer.loadLocal();
9470
}
9571

9672
@WorkerThread
9773
@Override
9874
public void clear() {
99-
mInMemorySegments.clear();
100-
mChangeNumber = -1;
101-
mPersistentStorage.clear();
75+
mProducer.clear();
10276
}
10377
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.split.android.client.storage.rbs;
2+
3+
import androidx.annotation.NonNull;
4+
5+
import java.util.Set;
6+
7+
import io.split.android.client.dtos.RuleBasedSegment;
8+
import io.split.android.client.storage.RolloutDefinitionsCache;
9+
10+
public interface RuleBasedSegmentStorageProducer extends RolloutDefinitionsCache {
11+
12+
boolean update(@NonNull Set<RuleBasedSegment> toAdd, @NonNull Set<RuleBasedSegment> toRemove, long changeNumber);
13+
}

0 commit comments

Comments
 (0)