Skip to content

Commit 9919904

Browse files
error policy
1 parent 3c7ffa8 commit 9919904

5 files changed

Lines changed: 118 additions & 62 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Microsoft.Extensions.Configuration;
2+
3+
namespace Config.SqlStreamStore
4+
{
5+
public static class ConfigurationBuilerExtensions
6+
{
7+
public static IConfigurationBuilder AddStreamStore(this IConfigurationBuilder builder,
8+
BuildStreamStoreFromConfig factory,
9+
bool subscribeToChanges = false,
10+
ErrorHandler errorHandler = null)
11+
{
12+
builder.Add(new StreamStoreConfigurationSource(factory)
13+
{
14+
SubscribeToChanges = subscribeToChanges,
15+
ErrorHandler = errorHandler
16+
});
17+
return builder;
18+
}
19+
20+
public static IConfigurationBuilder AddStreamStore(this IConfigurationBuilder builder,
21+
string connectionStringKey,
22+
BuildStreamStoreFromConnectionString factory,
23+
bool subscribeToChanges = false,
24+
ErrorHandler errorHandler = null)
25+
{
26+
builder.Add(new StreamStoreConfigurationSource(connectionStringKey, factory)
27+
{
28+
SubscribeToChanges = subscribeToChanges,
29+
ErrorHandler = errorHandler
30+
});
31+
return builder;
32+
}
33+
}
34+
}

src/Config.SqlStreamStore/StreamStoreConfigurationProvider.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Data;
34
using System.Linq;
45
using System.Threading;
56
using System.Threading.Tasks;
@@ -13,7 +14,7 @@ public class StreamStoreConfigurationProvider : ConfigurationProvider
1314
private readonly StreamStoreConfigurationSource _source;
1415
private readonly IConfigRepository _configRepository;
1516
private ConfigurationSettings _configurationSettings;
16-
17+
1718
public StreamStoreConfigurationProvider(StreamStoreConfigurationSource source,
1819
IConfigRepository configRepository)
1920
{
@@ -23,8 +24,29 @@ public StreamStoreConfigurationProvider(StreamStoreConfigurationSource source,
2324
}
2425
public override void Load()
2526
{
26-
_configurationSettings = _configRepository
27-
.GetLatest(CancellationToken.None).GetAwaiter().GetResult();
27+
int retryCount = 0;
28+
while (true)
29+
{
30+
31+
32+
try
33+
{
34+
_configurationSettings = _configRepository
35+
.GetLatest(CancellationToken.None).GetAwaiter().GetResult();
36+
37+
break;
38+
}
39+
catch (Exception ex)
40+
{
41+
if (_source.ErrorHandler == null)
42+
throw;
43+
44+
if (!_source.ErrorHandler(ex, retryCount++).GetAwaiter().GetResult())
45+
{
46+
throw;
47+
}
48+
}
49+
}
2850

2951
Data = _configurationSettings.ToDictionary(x => x.Key, x => x.Value, StringComparer.OrdinalIgnoreCase);
3052

src/Config.SqlStreamStore/StreamStoreConfigurationSource.cs

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,28 @@
11
using System;
2+
using System.Threading.Tasks;
23
using Microsoft.Extensions.Configuration;
34
using SqlStreamStore;
45

56
namespace Config.SqlStreamStore
67
{
7-
public static class ConfigurationBuilerExtensions
8-
{
9-
public static IConfigurationBuilder AddStreamStore(this IConfigurationBuilder builder,
10-
BuildStreamStoreFromConfig factory,
11-
bool subscribeToChanges = false)
12-
{
13-
builder.Add(new StreamStoreConfigurationSource(factory)
14-
{
15-
SubscribeToChanges = subscribeToChanges
16-
});
17-
return builder;
18-
}
19-
20-
public static IConfigurationBuilder AddStreamStore(this IConfigurationBuilder builder,
21-
string connectionStringKey,
22-
BuildStreamStoreFromConnectionString factory,
23-
bool subscribeToChanges = false)
24-
{
25-
builder.Add(new StreamStoreConfigurationSource(connectionStringKey, factory)
26-
{
27-
SubscribeToChanges = subscribeToChanges
28-
});
29-
return builder;
30-
}
31-
}
32-
338
public delegate IStreamStore BuildStreamStoreFromConnectionString(string connectionString);
349
public delegate IStreamStore BuildStreamStoreFromConfig(IConfigurationRoot configurationRoot);
3510
public delegate IConfigRepository BuildConfigRepository();
3611

12+
public delegate Task<bool> ErrorHandler(Exception ex, int retryCount);
13+
3714
public class StreamStoreConfigurationSource : IConfigurationSource
3815
{
3916

4017
private readonly BuildStreamStoreFromConfig _buildStreamStoreFromConfig;
4118

4219
public bool SubscribeToChanges { get; set; }
4320

21+
public ErrorHandler ErrorHandler { get; set; }
22+
4423
private readonly BuildConfigRepository _getConfigRepository;
4524

25+
4626
public StreamStoreConfigurationSource(BuildStreamStoreFromConfig buildStreamStoreFromConfig)
4727
{
4828
_buildStreamStoreFromConfig = buildStreamStoreFromConfig;

src/Config.SqlstreamStore.Example/Program.cs

Lines changed: 52 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,54 @@ static void Main(string[] args)
2727
.Build();
2828

2929
// On a background thread, create the database and start initializing
30-
Task.Run(() => CreateDatabase(ini["ConnectionString"], cts.Token), cts.Token);
30+
Task.Run(async () => await CreateDatabase(ini["ConnectionString"], cts.Token), cts.Token);
3131

32-
IStreamStore store = null;
32+
IStreamStore streamStore = null;
3333

3434
var sssConfig = new ConfigurationBuilder()
35+
36+
// Add the stream store configuration data
3537
.AddStreamStore(
3638
subscribeToChanges: true,
39+
40+
// When an error occurs while connecting to the database
41+
errorHandler: OnConnectError,
42+
3743
factory: config =>
38-
store = new MsSqlStreamStore(new MsSqlStreamStoreSettings(config["connectionString"]))
44+
// Create sql stream store instance. Uses connection string from ini file.
45+
// Note, we're assigning an instance variable here, so we can dispose the instance later
46+
streamStore = new MsSqlStreamStore(new MsSqlStreamStoreSettings(config["connectionString"]))
3947
)
48+
49+
// Also add the INI configuration data. This is where the connection string is read from
4050
.AddConfiguration(ini)
4151
.Build();
4252

53+
// Listen for configuration changes
4354
ChangeToken.OnChange(sssConfig.GetReloadToken, () =>
4455
{
4556
Console.WriteLine("Settings changed:");
4657
PrintSettings(sssConfig);
4758
});
4859

60+
// Print out the configuration settings present at startup
4961
Console.WriteLine("Found settings at startup:");
5062
PrintSettings(sssConfig);
5163

64+
65+
// Keep going until enter is pressed.
5266
Console.ReadLine();
67+
68+
// Stop the background thread and dispose SSS
5369
cts.Cancel();
54-
store.Dispose();
70+
streamStore.Dispose();
71+
}
72+
73+
private static async Task<bool> OnConnectError(Exception ex, int retryCount)
74+
{
75+
await Task.Delay(2000);
76+
Console.WriteLine($"Attempt {retryCount}, Sql Server is not yet available.. Retrying...");
77+
return true;
5578
}
5679

5780
private static void PrintSettings(IConfigurationRoot sssConfig)
@@ -65,37 +88,38 @@ private static void PrintSettings(IConfigurationRoot sssConfig)
6588

6689
private static async Task CreateDatabase(string connectionString, CancellationToken ct)
6790
{
68-
try
69-
{
70-
await Task.Delay(1000);
71-
Console.WriteLine("Creating database schema");
72-
await Task.Delay(3000);
91+
while(true)
92+
try
93+
{
94+
await Task.Delay(1000);
95+
Console.WriteLine("Creating database schema");
96+
await Task.Delay(3000);
7397

74-
var mgr = new DatabaseManager(connectionString);
75-
mgr.EnsureDatabaseExists(10, 10);
98+
var mgr = new DatabaseManager(connectionString);
99+
mgr.EnsureDatabaseExists(10, 10);
76100

77-
var msSqlStreamStoreSettings = new MsSqlStreamStoreSettings(connectionString);
101+
await Task.Delay(1000, ct);
78102

79-
var store = new MsSqlStreamStore(msSqlStreamStoreSettings);
80-
if (!(await store.CheckSchema(ct)).IsMatch())
81-
{
82-
await store.CreateSchema(ct);
83-
}
103+
var msSqlStreamStoreSettings = new MsSqlStreamStoreSettings(connectionString);
84104

85-
var repo = new ConfigRepository(store);
105+
var store = new MsSqlStreamStore(msSqlStreamStoreSettings);
106+
if (!(await store.CheckSchema(ct)).IsMatch())
107+
{
108+
await store.CreateSchema(ct);
109+
}
86110

87-
while (!ct.IsCancellationRequested)
111+
var repo = new ConfigRepository(store);
112+
113+
while (!ct.IsCancellationRequested)
114+
{
115+
await Task.Delay(1000, ct);
116+
await repo.Modify(ct, ("setting1", DateTime.Now.ToLongTimeString()));
117+
}
118+
}
119+
catch (Exception ex)
88120
{
89-
await Task.Delay(1000, ct);
90-
await repo.Modify(ct, ("setting1", DateTime.Now.ToLongTimeString()));
121+
Console.WriteLine("error while creating database: " + ex.Message);
91122
}
92-
}
93-
94-
catch (Exception ex)
95-
{
96-
Console.WriteLine("error while creating database: " + ex.Message);
97-
throw;
98-
}
99123
}
100124
}
101125

@@ -117,10 +141,6 @@ private string DatabaseName
117141
return databaseName;
118142
}
119143
}
120-
public void DropDatabase()
121-
{
122-
123-
}
124144

125145
public void EnsureDatabaseExists(int size, int fileGrowth)
126146
{
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ConnectionString = "server=(localdb)\mssqllocaldb;database=config"
1+
ConnectionString = "server=.;database=config;integrated security=true"

0 commit comments

Comments
 (0)