Skip to content

Commit

Permalink
Merge branch 'master' into 2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathansant committed Oct 12, 2023
2 parents d5a4ddb + ac05501 commit 72763cb
Show file tree
Hide file tree
Showing 15 changed files with 196 additions and 247 deletions.
20 changes: 13 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
## [1.5.0](https://github.com/jonathansant/orleans.persistence.redis/compare/1.4.1...1.5.0) (2023-02-21)
## [2.0.0](https://github.com/jonathansant/orleans.persistence.redis/compare/1.5.0...2.0.0) (2023-02-21)

### Features

- update to Orleans 7

## [1.5.0](https://github.com/jonathansant/orleans.persistence.redis/compare/1.4.1...1.5.0) (2023-02-21)

### Features

- Added a deflate unit tests (that verifies file integrity)
- Added BrotliCompression, DeflateCompression, GZipCompression and RawDeflateCompression modules that
- Added BrotliCompression, DeflateCompression, GZipCompression and RawDeflateCompression modules that
can be used to compress human serialized data

## [1.4.1](https://github.com/jonathansant/orleans.persistence.redis/compare/1.4.0...1.4.1) (2023-01-10)

### Features

- Added/Updated unit tests
- Refactored GrainStateStoregments enabled `DeleteOldSegments` in RedisStorageOptions

## [1.4.0](https://github.com/jonathansant/orleans.persistence.redis/compare/1.3.0...1.4.0) (2023-01-06)

### Features

- Added a feature to compress serialized data when using Orleans Serializer - can be enabled by
- Added a feature to compress serialized data when using Orleans Serializer - can be enabled by
calling: `AddDefaultRedisBrotliSerializer()` using Brotli Serialization
- Added a feature to segment data in chunks - this uses HashTable in redis - can be enabled by
setting option `SegmentSize` in RedisStorageOptions
- Option to delete unused Segments enabled `DeleteOldSegments` in RedisStorageOptions

## [1.3.0](https://github.com/jonathansant/orleans.persistence.redis/compare/1.2.2...1.3.0) (2023-01-02)

### Features
Expand All @@ -34,7 +40,7 @@

### Fix

- Align Default JsonSerializer settings across `ISiloHost` & `ISiloHostBuilderSettings`
- Align Default JsonSerializer settings across `ISiloHost` & `ISiloHostBuilderSettings`

## [1.2.1](https://github.com/jonathansant/orleans.persistence.redis/compare/1.2.0...1.2.1) (2021-07-12)

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</PropertyGroup>

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>

<!-- Shared Package Versions -->
Expand Down
301 changes: 121 additions & 180 deletions Orleans.Persistence.Redis/Config/RedisSiloHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,204 +18,145 @@
using OrleansSerializer = Orleans.Persistence.Redis.Serialization.OrleansSerializer;

// ReSharper disable once CheckNamespace
namespace Orleans.Hosting
namespace Orleans.Hosting;

public static class RedisSiloBuilderExtensions
{
public static class RedisSiloBuilderExtensions
public static RedisStorageOptionsBuilder AddRedisGrainStorage(
this ISiloBuilder builder,
string name
) => new RedisStorageOptionsBuilder(builder, name);

public static RedisStorageOptionsBuilder AddRedisGrainStorageAsDefault(
this ISiloBuilder builder
) => builder.AddRedisGrainStorage("Default");

internal static IServiceCollection AddRedisGrainStorage(
this IServiceCollection services,
string name,
Action<OptionsBuilder<RedisStorageOptions>> configureOptions = null
)
{
public static RedisStorageOptionsBuilder AddRedisGrainStorage(
this ISiloBuilder builder,
string name
) => new RedisStorageOptionsBuilder(builder, name);

public static RedisStorageOptionsBuilder AddRedisGrainStorageAsDefault(
this ISiloBuilder builder
) => builder.AddRedisGrainStorage("Default");

internal static ISiloBuilder AddRedisDefaultSerializer(this ISiloBuilder builder, string name)
=> builder.AddRedisSerializer<OrleansSerializer>(name);

internal static ISiloBuilder AddRedisDefaultHumanReadableSerializer(this ISiloBuilder builder, string name)
=> builder.AddRedisHumanReadableSerializer<JsonSerializer>(
name,
provider => new object[] { RedisDefaultJsonSerializerSettings.Get(provider) }
);

internal static ISiloBuilder AddCompression<TCompression>(this ISiloBuilder builder, string name)
where TCompression : ICompression
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<ICompression>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TCompression>(provider)));

internal static ISiloBuilder AddRedisSerializer<TSerializer>(
this ISiloBuilder builder,
string name,
params object[] settings
)
where TSerializer : ISerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<ISerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, settings))
);

internal static ISiloBuilder AddRedisHumanReadableSerializer<TSerializer>(
this ISiloBuilder builder,
string name,
params object[] settings
)
where TSerializer : IHumanReadableSerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<IHumanReadableSerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, settings))
);

internal static ISiloBuilder AddRedisHumanReadableSerializer<TSerializer>(
this ISiloBuilder builder,
string name,
Func<IServiceProvider, object[]> cfg
) where TSerializer : IHumanReadableSerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<IHumanReadableSerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, cfg?.Invoke(provider)))
);
configureOptions?.Invoke(services.AddOptions<RedisStorageOptions>(name));
// services.AddTransient<IConfigurationValidator>(sp => new DynamoDBGrainStorageOptionsValidator(sp.GetService<IOptionsSnapshot<RedisStorageOptions>>().Get(name), name));
services.AddSingletonNamedService(name, CreateStateStore);
services.ConfigureNamedOptionForLogging<RedisStorageOptions>(name);
services.TryAddSingleton(sp =>
sp.GetServiceByName<IGrainStorage>(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME));

return services
.AddSingletonNamedService(name, CreateDbConnection)
.AddSingletonNamedService(name, CreateRedisStorage)
.AddSingletonNamedService(name, (provider, n)
=> (ILifecycleParticipant<ISiloLifecycle>)provider.GetRequiredServiceByName<IGrainStorage>(n));
}

public static class RedisSiloHostBuilderExtensions
internal static ISiloBuilder AddRedisDefaultSerializer(this ISiloBuilder builder, string name)
=> builder.AddRedisSerializer<OrleansSerializer>(name);

internal static ISiloBuilder AddRedisDefaultBrotliSerializer(this ISiloBuilder builder, string name)
=> builder.AddRedisSerializer<BrotliSerializer>(name);

internal static ISiloBuilder AddRedisDefaultHumanReadableSerializer(this ISiloBuilder builder, string name)
=> builder.AddRedisHumanReadableSerializer<JsonSerializer>(
name,
provider => new object[] { RedisDefaultJsonSerializerSettings.Get(provider) }
);

internal static ISiloBuilder AddCompression<TCompression>(this ISiloBuilder builder, string name)
where TCompression : ICompression
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<ICompression>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TCompression>(provider)));

internal static ISiloBuilder AddRedisSerializer<TSerializer>(
this ISiloBuilder builder,
string name,
params object[] settings
)
where TSerializer : ISerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<ISerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, settings))
);

internal static ISiloBuilder AddRedisHumanReadableSerializer<TSerializer>(
this ISiloBuilder builder,
string name,
params object[] settings
)
where TSerializer : IHumanReadableSerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<IHumanReadableSerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, settings))
);

internal static ISiloBuilder AddRedisHumanReadableSerializer<TSerializer>(
this ISiloBuilder builder,
string name,
Func<IServiceProvider, object[]> cfg
) where TSerializer : IHumanReadableSerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<IHumanReadableSerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, cfg?.Invoke(provider)))
);

private static IGrainStorage CreateRedisStorage(IServiceProvider services, string name)
{
public static RedisStorageSiloHostBuilderOptionsBuilder AddRedisGrainStorage(
this ISiloHostBuilder builder,
string name
) => new RedisStorageSiloHostBuilderOptionsBuilder(builder, name);

public static RedisStorageSiloHostBuilderOptionsBuilder AddRedisGrainStorageAsDefault(
this ISiloHostBuilder builder
) => builder.AddRedisGrainStorage("Default");

internal static IServiceCollection AddRedisGrainStorage(
this IServiceCollection services,
string name,
Action<OptionsBuilder<RedisStorageOptions>> configureOptions = null
)
{
configureOptions?.Invoke(services.AddOptions<RedisStorageOptions>(name));
// services.AddTransient<IConfigurationValidator>(sp => new DynamoDBGrainStorageOptionsValidator(sp.GetService<IOptionsSnapshot<RedisStorageOptions>>().Get(name), name));
services.AddSingletonNamedService(name, CreateStateStore);
services.ConfigureNamedOptionForLogging<RedisStorageOptions>(name);
services.TryAddSingleton(sp =>
sp.GetServiceByName<IGrainStorage>(ProviderConstants.DEFAULT_STORAGE_PROVIDER_NAME));

return services
.AddSingletonNamedService(name, CreateDbConnection)
.AddSingletonNamedService(name, CreateRedisStorage)
.AddSingletonNamedService(name, (provider, n)
=> (ILifecycleParticipant<ISiloLifecycle>)provider.GetRequiredServiceByName<IGrainStorage>(n));
}

internal static ISiloHostBuilder AddRedisDefaultSerializer(this ISiloHostBuilder builder, string name)
=> builder.AddRedisSerializer<OrleansSerializer>(name);

internal static ISiloHostBuilder AddRedisDefaultBrotliSerializer(this ISiloHostBuilder builder, string name)
=> builder.AddRedisSerializer<BrotliSerializer>(name);

internal static ISiloHostBuilder AddRedisDefaultHumanReadableSerializer(this ISiloHostBuilder builder,
string name)
=> builder.AddRedisHumanReadableSerializer<JsonSerializer>(
name,
provider => new object[] { RedisDefaultJsonSerializerSettings.Get(provider) });

internal static ISiloHostBuilder AddRedisSerializer<TSerializer>(this ISiloHostBuilder builder, string name,
params object[] settings)
where TSerializer : ISerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<ISerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, settings))
);

internal static ISiloHostBuilder AddRedisHumanReadableSerializer<TSerializer>(this ISiloHostBuilder builder,
string name, params object[] settings)
where TSerializer : IHumanReadableSerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<IHumanReadableSerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, settings))
);

internal static ISiloHostBuilder AddRedisHumanReadableSerializer<TSerializer>(
this ISiloHostBuilder builder,
string name,
Func<IServiceProvider, object[]> cfg
) where TSerializer : IHumanReadableSerializer
=> builder.ConfigureServices(services =>
services.AddSingletonNamedService<IHumanReadableSerializer>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TSerializer>(provider, cfg?.Invoke(provider)))
);

internal static ISiloHostBuilder AddCompression<TCompression>(this ISiloHostBuilder builder, string name)
where TCompression : ICompression
{
return builder.ConfigureServices(services =>
services.AddSingletonNamedService<ICompression>(name, (provider, n)
=> ActivatorUtilities.CreateInstance<TCompression>(provider)));
}

private static IGrainStorage CreateRedisStorage(IServiceProvider services, string name)
{
var store = services.GetRequiredServiceByName<IGrainStateStore>(name);
var connection = services.GetRequiredServiceByName<DbConnection>(name);
return ActivatorUtilities.CreateInstance<RedisGrainStorage>(services, name, store, connection);
}
var store = services.GetRequiredServiceByName<IGrainStateStore>(name);
var connection = services.GetRequiredServiceByName<DbConnection>(name);
return ActivatorUtilities.CreateInstance<RedisGrainStorage>(services, name, store, connection);
}

private static IGrainStateStore CreateStateStore(IServiceProvider provider, string name)
{
var connection = provider.GetRequiredServiceByName<DbConnection>(name);
var serializer = provider.GetRequiredServiceByName<ISerializer>(name);
var humanReadableSerializer = provider.GetServiceByName<IHumanReadableSerializer>(name);
var options = provider.GetRequiredService<IOptionsSnapshot<RedisStorageOptions>>();
var compress = provider.GetServiceByName<ICompression>(name);

if (compress != null)
return ActivatorUtilities.CreateInstance<GrainStateStore>(
provider,
connection,
options.Get(name),
serializer,
humanReadableSerializer,
compress
);
private static IGrainStateStore CreateStateStore(IServiceProvider provider, string name)
{
var connection = provider.GetRequiredServiceByName<DbConnection>(name);
var serializer = provider.GetRequiredServiceByName<ISerializer>(name);
var humanReadableSerializer = provider.GetServiceByName<IHumanReadableSerializer>(name);
var options = provider.GetRequiredService<IOptionsSnapshot<RedisStorageOptions>>();
var compress = provider.GetServiceByName<ICompression>(name);

if (compress != null)
return ActivatorUtilities.CreateInstance<GrainStateStore>(
provider,
connection,
options.Get(name),
serializer,
humanReadableSerializer
humanReadableSerializer,
compress
);
}

private static DbConnection CreateDbConnection(IServiceProvider provider, string name)
{
var optionsSnapshot = provider.GetRequiredService<IOptionsSnapshot<RedisStorageOptions>>();
var logger = provider.GetRequiredService<ILogger<DbConnection>>();
return ActivatorUtilities.CreateInstance<DbConnection>(provider, optionsSnapshot.Get(name), logger);
}
return ActivatorUtilities.CreateInstance<GrainStateStore>(
provider,
connection,
options.Get(name),
serializer,
humanReadableSerializer
);
}

public static class RedisDefaultJsonSerializerSettings
private static DbConnection CreateDbConnection(IServiceProvider provider, string name)
{
public static JsonSerializerSettings Get(IServiceProvider provider)
{
var settings = OrleansJsonSerializer.GetDefaultSerializerSettings(
provider.GetRequiredService<ITypeResolver>(),
provider.GetRequiredService<IGrainFactory>()
);
var optionsSnapshot = provider.GetRequiredService<IOptionsSnapshot<RedisStorageOptions>>();
var logger = provider.GetRequiredService<ILogger<DbConnection>>();
return ActivatorUtilities.CreateInstance<DbConnection>(provider, optionsSnapshot.Get(name), logger);
}
}

settings.ContractResolver = new DefaultContractResolver
public static class RedisDefaultJsonSerializerSettings
{
public static JsonSerializerSettings Get(IServiceProvider provider)
{
var settings = OrleansJsonSerializerSettings.GetDefaultSerializerSettings(provider);

settings.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new DefaultNamingStrategy
{
NamingStrategy = new DefaultNamingStrategy
{
ProcessDictionaryKeys = false
}
};

return settings;
}
ProcessDictionaryKeys = false
}
};

return settings;
}
}
Loading

0 comments on commit 72763cb

Please sign in to comment.