-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathFDv2DataSystem.cs
More file actions
136 lines (115 loc) · 5.72 KB
/
Copy pathFDv2DataSystem.cs
File metadata and controls
136 lines (115 loc) · 5.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LaunchDarkly.Logging;
using LaunchDarkly.Sdk.Server.Interfaces;
using LaunchDarkly.Sdk.Server.Internal.DataSources;
using LaunchDarkly.Sdk.Server.Internal.DataStores;
using LaunchDarkly.Sdk.Server.Internal.FDv2DataSources;
using LaunchDarkly.Sdk.Server.Subsystems;
namespace LaunchDarkly.Sdk.Server.Internal.DataSystem
{
internal class FDv2DataSystem : IDataSystem, IDisposable
{
private readonly WriteThroughStore _store;
private readonly IDataSource _dataSource;
private readonly DataSourceUpdatesImpl _dataSourceUpdates;
private bool _disposed;
#region IDataSystem implementation
public IReadOnlyStore Store { get; }
public Task<bool> Start() => _dataSource.Start();
public bool Initialized => _dataSource.Initialized;
public IFlagChanged FlagChanged { get; }
public IDataSourceStatusProvider DataSourceStatusProvider { get; }
public IDataStoreStatusProvider DataStoreStatusProvider { get; }
#endregion
private FDv2DataSystem(
WriteThroughStore store,
IDataSource dataSource,
IDataSourceStatusProvider dataSourceStatusProvider,
IDataStoreStatusProvider dataStoreStatusProvider,
DataSourceUpdatesImpl dataStoreUpdates
)
{
_store = store;
_dataSource = dataSource;
DataStoreStatusProvider = dataStoreStatusProvider;
DataSourceStatusProvider = dataSourceStatusProvider;
FlagChanged = new FlagChangedFacade(dataStoreUpdates);
_dataSourceUpdates = dataStoreUpdates;
Store = new ReadonlyStoreFacade(store);
}
public static FDv2DataSystem Create(Logger logger, Configuration configuration, LdClientContext clientContext,
LoggingConfiguration logConfig)
{
var dataSystemConfiguration = configuration.DataSystem.Build();
var dataStoreUpdates =
new DataStoreUpdatesImpl(clientContext.TaskExecutor, logger.SubLogger(LogNames.DataStoreSubLog));
var memoryStore = new InMemoryDataStore();
var persistentStore =
dataSystemConfiguration.PersistentStore?.Build(clientContext.WithDataStoreUpdates(dataStoreUpdates));
// Configure persistent store to sync from memory store during recovery (ReadWrite mode only)
if (persistentStore != null &&
dataSystemConfiguration.PersistentDataStoreMode == DataSystemConfiguration.DataStoreMode.ReadWrite)
{
if (persistentStore is ISettableCache externalSourceSupport)
{
externalSourceSupport.SetCacheExporter(memoryStore);
}
}
var writeThroughStore = new WriteThroughStore(memoryStore, persistentStore,
dataSystemConfiguration.PersistentDataStoreMode);
var dataStoreStatusProvider = new DataStoreStatusProviderImpl(writeThroughStore, dataStoreUpdates);
var dataSourceUpdates = new DataSourceUpdatesImpl(writeThroughStore, dataStoreStatusProvider,
clientContext.TaskExecutor, logger, logConfig.LogDataSourceOutageAsErrorAfter);
var contextWithSelectorSource =
clientContext.WithSelectorSource(new SelectorSourceFacade(writeThroughStore));
// FDv1 fallback synchronizer is optional; only build a list entry when one is
// configured. An always-present list entry that captured a null configurer would
// throw NRE the moment the action applier advanced to the FDv1 fallback entry.
var fdv1FallbackFactories = dataSystemConfiguration.FDv1FallbackSynchronizer == null
? new List<SourceFactory>()
: new List<SourceFactory>
{
FactoryWithContext(clientContext)(dataSystemConfiguration.FDv1FallbackSynchronizer)
};
var compositeDataSource = configuration.Offline ? Components.ExternalUpdatesOnly.Build(contextWithSelectorSource) : FDv2DataSource.CreateFDv2DataSource(
dataSourceUpdates,
dataSystemConfiguration.Initializers.Select(FactoryWithContext(contextWithSelectorSource)).ToList(),
dataSystemConfiguration.Synchronizers.Select(FactoryWithContext(contextWithSelectorSource)).ToList(),
fdv1FallbackFactories,
logger
);
var dataSourceStatusProvider = new DataSourceStatusProviderImpl(dataSourceUpdates);
return new FDv2DataSystem(writeThroughStore, compositeDataSource, dataSourceStatusProvider,
dataStoreStatusProvider, dataSourceUpdates);
}
private static Func<IComponentConfigurer<IDataSource>, SourceFactory> FactoryWithContext(
LdClientContext clientContext)
{
return (dataSourceFactory) => ToSourceFactory(dataSourceFactory, clientContext);
}
private static SourceFactory ToSourceFactory(IComponentConfigurer<IDataSource> dataSourceFactory,
LdClientContext clientContext)
{
return (sink) =>
dataSourceFactory.Build(clientContext.WithDataSourceUpdates(new DataSourceUpdatesV2ToV1Adapter(sink)));
}
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
_dataSource.Dispose();
_store.Dispose();
_dataSourceUpdates.Dispose();
}
_disposed = true;
}
}
}