Skip to content

Commit aed253a

Browse files
committed
New Grain state serializer
1 parent 90c753c commit aed253a

16 files changed

+401
-190
lines changed

Directory.Build.props

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<MicrosoftDotNetPlatformAbstractionsVersion>3.1.6</MicrosoftDotNetPlatformAbstractionsVersion>
4848
<SystemSecurityCryptographyCngVersion>5.0.0</SystemSecurityCryptographyCngVersion>
4949
<SystemIoPipelinesVersion>5.0.0</SystemIoPipelinesVersion>
50+
<SystemMemoryData>1.0.1</SystemMemoryData>
5051

5152
<!-- Microsoft packages -->
5253
<MicrosoftBuildVersion>16.9.0</MicrosoftBuildVersion>

src/Azure/Orleans.Persistence.AzureStorage/Hosting/AzureBlobSiloBuilderExtensions.cs

+28-31
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ public static ISiloBuilder AddAzureBlobGrainStorageAsDefault(this ISiloBuilder b
2525
/// </summary>
2626
public static ISiloBuilder AddAzureBlobGrainStorage(this ISiloBuilder builder, string name, Action<AzureBlobStorageOptions> configureOptions)
2727
{
28-
return builder.ConfigureServices(services => services.AddAzureBlobGrainStorage(name, configureOptions));
28+
return builder.AddGrainStorage(name, configure =>
29+
{
30+
configure.UseOrleansSerializer();
31+
configure.UseAzureBlob(configureOptions);
32+
});
2933
}
3034

3135
/// <summary>
@@ -41,48 +45,41 @@ public static ISiloBuilder AddAzureBlobGrainStorageAsDefault(this ISiloBuilder b
4145
/// </summary>
4246
public static ISiloBuilder AddAzureBlobGrainStorage(this ISiloBuilder builder, string name, Action<OptionsBuilder<AzureBlobStorageOptions>> configureOptions = null)
4347
{
44-
return builder.ConfigureServices(services => services.AddAzureBlobGrainStorage(name, configureOptions));
48+
return builder.AddGrainStorage(name, configure =>
49+
{
50+
configure.UseOrleansSerializer();
51+
configure.UseAzureBlob(configureOptions);
52+
});
4553
}
4654

4755
/// <summary>
48-
/// Configure silo to use azure blob storage as the default grain storage.
56+
/// Use Azure Blob as grain storage
4957
/// </summary>
50-
public static IServiceCollection AddAzureBlobGrainStorageAsDefault(this IServiceCollection services, Action<AzureBlobStorageOptions> configureOptions)
58+
public static void UseAzureBlob(this IGrainStorageProviderConfigurator configurator, Action<AzureBlobStorageOptions> options)
5159
{
52-
return services.AddAzureBlobGrainStorage(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME, ob => ob.Configure(configureOptions));
60+
configurator.UseAzureBlob(builder => builder.Configure(options));
5361
}
5462

5563
/// <summary>
56-
/// Configure silo to use azure blob storage for grain storage.
64+
/// Use Azure Blob as grain storage
5765
/// </summary>
58-
public static IServiceCollection AddAzureBlobGrainStorage(this IServiceCollection services, string name, Action<AzureBlobStorageOptions> configureOptions)
66+
public static void UseAzureBlob(this IGrainStorageProviderConfigurator configurator, Action<OptionsBuilder<AzureBlobStorageOptions>> configureOptions)
5967
{
60-
return services.AddAzureBlobGrainStorage(name, ob => ob.Configure(configureOptions));
61-
}
68+
configurator.ConfigureStorage(AzureBlobGrainStorageFactory.Create, configureOptions);
69+
configurator.ConfigureDelegate.Invoke(services =>
70+
{
71+
if (string.Equals(configurator.Name, ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME, StringComparison.Ordinal))
72+
{
73+
services.TryAddSingleton(sp => sp.GetServiceByName<IGrainStorage>(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME));
74+
}
6275

63-
/// <summary>
64-
/// Configure silo to use azure blob storage as the default grain storage.
65-
/// </summary>
66-
public static IServiceCollection AddAzureBlobGrainStorageAsDefault(this IServiceCollection services, Action<OptionsBuilder<AzureBlobStorageOptions>> configureOptions = null)
67-
{
68-
return services.AddAzureBlobGrainStorage(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME, configureOptions);
69-
}
76+
services.AddSingletonNamedService(
77+
configurator.Name,
78+
(s, n) => (ILifecycleParticipant<ISiloLifecycle>)s.GetRequiredServiceByName<IGrainStorage>(n));
7079

71-
/// <summary>
72-
/// Configure silo to use azure blob storage for grain storage.
73-
/// </summary>
74-
public static IServiceCollection AddAzureBlobGrainStorage(this IServiceCollection services, string name,
75-
Action<OptionsBuilder<AzureBlobStorageOptions>> configureOptions = null)
76-
{
77-
configureOptions?.Invoke(services.AddOptions<AzureBlobStorageOptions>(name));
78-
services.AddTransient<IConfigurationValidator>(sp => new AzureBlobStorageOptionsValidator(sp.GetRequiredService<IOptionsMonitor<AzureBlobStorageOptions>>().Get(name), name));
79-
services.ConfigureNamedOptionForLogging<AzureBlobStorageOptions>(name);
80-
if (string.Equals(name, ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME, StringComparison.Ordinal))
81-
{
82-
services.TryAddSingleton(sp => sp.GetServiceByName<IGrainStorage>(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME));
83-
}
84-
return services.AddSingletonNamedService<IGrainStorage>(name, AzureBlobGrainStorageFactory.Create)
85-
.AddSingletonNamedService<ILifecycleParticipant<ISiloLifecycle>>(name, (s, n) => (ILifecycleParticipant<ISiloLifecycle>)s.GetRequiredServiceByName<IGrainStorage>(n));
80+
services.AddTransient<IConfigurationValidator>(
81+
sp => new AzureBlobStorageOptionsValidator(sp.GetRequiredService<IOptionsMonitor<AzureBlobStorageOptions>>().Get(configurator.Name), configurator.Name));
82+
});
8683
}
8784
}
8885
}

src/Azure/Orleans.Persistence.AzureStorage/Hosting/AzureTableSiloBuilderExtensions.cs

+31-12
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public static ISiloBuilder AddAzureTableGrainStorageAsDefault(this ISiloBuilder
2424
/// </summary>
2525
public static ISiloBuilder AddAzureTableGrainStorage(this ISiloBuilder builder, string name, Action<AzureTableStorageOptions> configureOptions)
2626
{
27-
return builder.ConfigureServices(services => services.AddAzureTableGrainStorage(name, ob => ob.Configure(configureOptions)));
27+
return builder.AddAzureTableGrainStorage(name, ob => ob.Configure(configureOptions));
2828
}
2929

3030
/// <summary>
@@ -40,21 +40,40 @@ public static ISiloBuilder AddAzureTableGrainStorageAsDefault(this ISiloBuilder
4040
/// </summary>
4141
public static ISiloBuilder AddAzureTableGrainStorage(this ISiloBuilder builder, string name, Action<OptionsBuilder<AzureTableStorageOptions>> configureOptions = null)
4242
{
43-
return builder.ConfigureServices(services => services.AddAzureTableGrainStorage(name, configureOptions));
43+
return builder.AddGrainStorage(name, configure =>
44+
{
45+
configure.UseAzureTable(configureOptions);
46+
configure.UseOrleansSerializer();
47+
});
48+
}
49+
50+
/// <summary>
51+
/// Use Azure Table as grain storage
52+
/// </summary>
53+
public static void UseAzureTable(this IGrainStorageProviderConfigurator configurator, Action<AzureTableStorageOptions> options)
54+
{
55+
configurator.UseAzureTable(builder => builder.Configure(options));
4456
}
4557

46-
internal static IServiceCollection AddAzureTableGrainStorage(this IServiceCollection services, string name,
47-
Action<OptionsBuilder<AzureTableStorageOptions>> configureOptions = null)
58+
/// <summary>
59+
/// Use Azure Table as grain storage
60+
/// </summary>
61+
public static void UseAzureTable(this IGrainStorageProviderConfigurator configurator, Action<OptionsBuilder<AzureTableStorageOptions>> configureOptions)
4862
{
49-
configureOptions?.Invoke(services.AddOptions<AzureTableStorageOptions>(name));
50-
services.AddTransient<IConfigurationValidator>(sp => new AzureTableGrainStorageOptionsValidator(sp.GetRequiredService<IOptionsMonitor<AzureTableStorageOptions>>().Get(name), name));
51-
services.ConfigureNamedOptionForLogging<AzureTableStorageOptions>(name);
52-
if (string.Equals(name, ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME, StringComparison.Ordinal))
63+
configurator.ConfigureStorage(AzureTableGrainStorageFactory.Create, configureOptions);
64+
configurator.ConfigureDelegate.Invoke(services =>
5365
{
54-
services.TryAddSingleton(sp => sp.GetServiceByName<IGrainStorage>(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME));
55-
}
56-
return services.AddSingletonNamedService<IGrainStorage>(name, AzureTableGrainStorageFactory.Create)
57-
.AddSingletonNamedService<ILifecycleParticipant<ISiloLifecycle>>(name, (s, n) => (ILifecycleParticipant<ISiloLifecycle>)s.GetRequiredServiceByName<IGrainStorage>(n));
66+
if (string.Equals(configurator.Name, ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME, StringComparison.Ordinal))
67+
{
68+
services.TryAddSingleton(sp => sp.GetServiceByName<IGrainStorage>(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME));
69+
}
70+
71+
services.AddSingletonNamedService(
72+
configurator.Name,
73+
(s, n) => (ILifecycleParticipant<ISiloLifecycle>)s.GetRequiredServiceByName<IGrainStorage>(n));
74+
75+
services.AddTransient<IConfigurationValidator>(sp => new AzureTableGrainStorageOptionsValidator(sp.GetRequiredService<IOptionsMonitor<AzureTableStorageOptions>>().Get(configurator.Name), configurator.Name));
76+
});
5877
}
5978
}
6079
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.DependencyInjection.Extensions;
4+
using Microsoft.Extensions.Options;
5+
using Orleans.Storage;
6+
7+
namespace Orleans.Hosting
8+
{
9+
/// <summary>
10+
/// Base interface for configuring the grain storage providers
11+
/// </summary>
12+
public interface IGrainStorageProviderConfigurator : INamedServiceConfigurator
13+
{
14+
}
15+
16+
/// <summary>
17+
/// Class used to configuring the grain storage providers
18+
/// </summary>
19+
public class GrainStorageProviderConfigurator : NamedServiceConfigurator, IGrainStorageProviderConfigurator
20+
{
21+
public GrainStorageProviderConfigurator(
22+
string name,
23+
Action<Action<IServiceCollection>> configureDelegate)
24+
: base(name, configureDelegate)
25+
{
26+
}
27+
}
28+
29+
public static class GrainStorageProviderConfiguratorExtensions
30+
{
31+
/// <summary>
32+
/// Set the serializer to use
33+
/// </summary>
34+
public static void ConfigureSerializer(
35+
this IGrainStorageProviderConfigurator self,
36+
Func<IServiceProvider, string, IGrainStorageSerializer> factory)
37+
{
38+
self.ConfigureComponent(factory);
39+
}
40+
41+
/// <summary>
42+
/// Configure the storage to use
43+
/// </summary>
44+
public static void ConfigureStorage<T>(
45+
this IGrainStorageProviderConfigurator self,
46+
Func<IServiceProvider, string, IGrainStorage> grainStorageFactory,
47+
Action<OptionsBuilder<T>> configureOptions)
48+
where T : class, new()
49+
{
50+
self.ConfigureComponent(grainStorageFactory, configureOptions);
51+
}
52+
53+
/// <summary>
54+
/// Use the Orleans built-in serializer.
55+
/// Fast, but not backward compatible, and hard to use outside Orleans
56+
/// </summary>
57+
public static void UseOrleansSerializer(this IGrainStorageProviderConfigurator self, bool useJsonAsFallback = true)
58+
{
59+
self.ConfigureDelegate.Invoke(sp => sp.TryAddSingleton<OrleansGrainStorageSerializer>());
60+
if (useJsonAsFallback)
61+
{
62+
self.ConfigureDelegate.Invoke(sp => sp.TryAddSingleton<JsonGrainStorageSerializer>());
63+
self.ConfigureSerializer((sp, name) => new GrainStorageSerializer(sp.GetService<OrleansGrainStorageSerializer>(), sp.GetService<JsonGrainStorageSerializer>()));
64+
}
65+
else
66+
{
67+
self.ConfigureSerializer((sp, name) => sp.GetService<OrleansGrainStorageSerializer>());
68+
}
69+
}
70+
71+
/// <summary>
72+
/// Use the Orleans built-in serializer.
73+
/// Fast, but not backward compatible, and hard to use outside Orleans
74+
/// </summary>
75+
public static void UseJsonSerializer(this IGrainStorageProviderConfigurator self, bool useOrleansBinaryAsFallback = true)
76+
{
77+
self.ConfigureDelegate.Invoke(sp => sp.TryAddSingleton<JsonGrainStorageSerializer>());
78+
self.ConfigureSerializer((sp, name) => sp.GetService<JsonGrainStorageSerializer>());
79+
if (useOrleansBinaryAsFallback)
80+
{
81+
self.ConfigureDelegate.Invoke(sp => sp.TryAddSingleton<OrleansGrainStorageSerializer>());
82+
self.ConfigureSerializer((sp, name) => new GrainStorageSerializer(sp.GetService<JsonGrainStorageSerializer>(), sp.GetService<OrleansGrainStorageSerializer>()));
83+
}
84+
else
85+
{
86+
self.ConfigureSerializer((sp, name) => sp.GetService<OrleansGrainStorageSerializer>());
87+
}
88+
}
89+
90+
/// <summary>
91+
/// Add a grain storage provider
92+
/// </summary>
93+
public static ISiloBuilder AddGrainStorage(this ISiloBuilder self, string name, Action<IGrainStorageProviderConfigurator> configure)
94+
{
95+
var configurator = new GrainStorageProviderConfigurator(name, configureDelegate => self.ConfigureServices(configureDelegate));
96+
configure.Invoke(configurator);
97+
return self;
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)