Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.launchdarkly.sdk.server;
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.launchdarkly.sdk.server.integrations.PersistentDataStoreBuilder;
import com.launchdarkly.sdk.server.interfaces.DataStore;
import com.launchdarkly.sdk.server.interfaces.DataStoreStatusProvider.CacheStats;
import com.launchdarkly.sdk.server.interfaces.DataStoreTypes.DataKind;
import com.launchdarkly.sdk.server.interfaces.DataStoreTypes.FullDataSet;
import com.launchdarkly.sdk.server.interfaces.DataStoreTypes.ItemDescriptor;
import com.launchdarkly.sdk.server.interfaces.DataStoreTypes.KeyedItems;
import com.launchdarkly.sdk.server.interfaces.DataStoreTypes.SerializedItemDescriptor;
import com.launchdarkly.sdk.server.interfaces.DataStoreUpdates;
import com.launchdarkly.sdk.server.interfaces.PersistentDataStore;
import org.slf4j.Logger;
import java.io.IOException;
import java.time.Duration;
import java.util.AbstractMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.isEmpty;
/**
* Package-private implementation of {@link DataStore} that delegates the basic functionality to an
* instance of {@link PersistentDataStore}. It provides optional caching behavior and other logic that
* would otherwise be repeated in every data store implementation. This makes it easier to create new
* database integrations by implementing only the database-specific logic.
*
* This class is only constructed by {@link PersistentDataStoreBuilder}.
*/
final class PersistentDataStoreWrapper implements DataStore {
private static final Logger logger = Loggers.DATA_STORE;
private final PersistentDataStore core;
private final LoadingCache> itemCache;
private final LoadingCache> allCache;
private final LoadingCache initCache;
private final PersistentDataStoreStatusManager statusManager;
private final boolean cacheIndefinitely;
private final Set cachedDataKinds = new HashSet<>(); // this map is used in pollForAvailability()
private final AtomicBoolean inited = new AtomicBoolean(false);
private final ListeningExecutorService cacheExecutor;
PersistentDataStoreWrapper(
final PersistentDataStore core,
Duration cacheTtl,
PersistentDataStoreBuilder.StaleValuesPolicy staleValuesPolicy,
boolean recordCacheStats,
DataStoreUpdates dataStoreUpdates,
ScheduledExecutorService sharedExecutor
) {
this.core = core;
if (cacheTtl.isZero()) {
itemCache = null;
allCache = null;
initCache = null;
cacheExecutor = null;
cacheIndefinitely = false;
} else {
cacheIndefinitely = cacheTtl.isNegative();
CacheLoader> itemLoader = new CacheLoader>() {
@Override
public Optional load(CacheKey key) throws Exception {
return Optional.fromNullable(getAndDeserializeItem(key.kind, key.key));
}
};
CacheLoader> allLoader = new CacheLoader>() {
@Override
public KeyedItems load(DataKind kind) throws Exception {
return getAllAndDeserialize(kind);
}
};
CacheLoader initLoader = new CacheLoader() {
@Override
public Boolean load(String key) throws Exception {
return core.isInitialized();
}
};
if (staleValuesPolicy == PersistentDataStoreBuilder.StaleValuesPolicy.REFRESH_ASYNC) {
cacheExecutor = MoreExecutors.listeningDecorator(sharedExecutor);
// Note that the REFRESH_ASYNC mode is only used for itemCache, not allCache, since retrieving all flags is
// less frequently needed and we don't want to incur the extra overhead.
itemLoader = CacheLoader.asyncReloading(itemLoader, cacheExecutor);
} else {
cacheExecutor = null;
}
itemCache = newCacheBuilder(cacheTtl, staleValuesPolicy, recordCacheStats).build(itemLoader);
allCache = newCacheBuilder(cacheTtl, staleValuesPolicy, recordCacheStats).build(allLoader);
initCache = newCacheBuilder(cacheTtl, staleValuesPolicy, recordCacheStats).build(initLoader);
}
statusManager = new PersistentDataStoreStatusManager(
!cacheIndefinitely,
true,
this::pollAvailabilityAfterOutage,
dataStoreUpdates::updateStatus,
sharedExecutor
);
}
private static CacheBuilder