Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/persistence.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
`Itmo.Dev.Platform.Persistence.Postgres` с реализациями для БД Postgres.

Для регистрации в DI-контейнере необходимо вызвать метод `AddPlatformPersistence`, предварительно зарегистрировав саму
платформу (метод `AddPlatform`).
платформу (метод `AddPlatform`, в нём необходимо выбрать сериализатор).
Метод принимает делегат, в котором происходит конфигурация Persistence слоя.

```csharp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
.AddOptions<BackgroundTaskPersistenceOptions>()
.Configure(o => persistenceOptions.Value.ApplyTo(o));

collection.AddPlatform();
collection.AddPlatform(config => config.WithSystemTextJsonConfiguration());

collection.AddPlatformPersistence(
persistence => persistence.UsePostgres(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
using Itmo.Dev.Platform.BackgroundTasks.Tasks.Metadata;
using Itmo.Dev.Platform.BackgroundTasks.Tasks.Results;
using Itmo.Dev.Platform.Common.Models;
using Itmo.Dev.Platform.Common.Serialization;
using Itmo.Dev.Platform.Persistence.Abstractions.Connections;
using Itmo.Dev.Platform.Persistence.Postgres.Extensions;
using Newtonsoft.Json;
using System.Data;
using System.Runtime.CompilerServices;

Expand All @@ -18,20 +18,20 @@ namespace Itmo.Dev.Platform.BackgroundTasks.Postgres.Repositories;
internal class BackgroundTaskRepository : IBackgroundTaskInfrastructureRepository
{
private readonly BackgroundTaskQueryStorage _queryStorage;
private readonly JsonSerializerSettings _serializerSettings;
private readonly IBackgroundTaskRegistry _backgroundTaskRegistry;
private readonly IPersistenceConnectionProvider _connectionProvider;
private readonly IPlatformSerializer _serializer;

public BackgroundTaskRepository(
BackgroundTaskQueryStorage queryStorage,
IPersistenceConnectionProvider connectionProvider,
JsonSerializerSettings serializerSettings,
IBackgroundTaskRegistry backgroundTaskRegistry)
IBackgroundTaskRegistry backgroundTaskRegistry,
IPlatformSerializer serializer)
{
_queryStorage = queryStorage;
_connectionProvider = connectionProvider;
_serializerSettings = serializerSettings;
_backgroundTaskRegistry = backgroundTaskRegistry;
_serializer = serializer;
}

public async IAsyncEnumerable<BackgroundTask> QueryAsync(
Expand All @@ -48,8 +48,8 @@ public async IAsyncEnumerable<BackgroundTask> QueryAsync(
.AddParameter("ids", query.Ids.Select(x => x.Value).ToArray())
.AddParameter("names", query.Names)
.AddParameter("states", query.States)
.AddJsonArrayParameter("metadata", query.Metadatas, _serializerSettings)
.AddJsonArrayParameter("execution_metadata", query.ExecutionMetadatas, _serializerSettings)
.AddJsonArrayParameter("metadata", query.Metadatas)
.AddJsonArrayParameter("execution_metadata", query.ExecutionMetadatas)
.AddParameter("cursor", query.Cursor)
.AddParameter("max_scheduled_at", query.MaxScheduledAt)
.AddParameter("page_size", query.PageSize ?? int.MaxValue);
Expand Down Expand Up @@ -99,7 +99,7 @@ public async IAsyncEnumerable<BackgroundTaskId> SearchIdsAsync(
.AddParameter("ids", query.Ids.Select(x => x.Value).ToArray())
.AddParameter("names", query.Names)
.AddParameter("states", query.States)
.AddJsonArrayParameter("metadata", query.Metadatas, _serializerSettings)
.AddJsonArrayParameter("metadata", query.Metadatas)
.AddParameter("max_scheduled_at", query.MaxScheduledAt)
.AddParameter("cursor", query.Cursor)
.AddParameter("page_size", query.PageSize ?? int.MaxValue);
Expand All @@ -123,8 +123,8 @@ public async IAsyncEnumerable<BackgroundTaskId> AddRangeAsync(
.AddParameter("types", tasks.Select(x => x.Type.AssemblyQualifiedName).ToArray())
.AddParameter("scheduled_at", tasks.Select(x => x.ScheduledAt))
.AddParameter("created_at", tasks.Select(x => x.CreatedAt).ToArray())
.AddJsonArrayParameter("metadata", tasks.Select(x => x.Metadata), _serializerSettings)
.AddJsonArrayParameter("execution_metadata", tasks.Select(x => x.ExecutionMetadata), _serializerSettings);
.AddJsonArrayParameter("metadata", tasks.Select(x => x.Metadata))
.AddJsonArrayParameter("execution_metadata", tasks.Select(x => x.ExecutionMetadata));

await using var reader = await command.ExecuteReaderAsync(cancellationToken);

Expand Down Expand Up @@ -156,9 +156,9 @@ public async Task UpdateAsync(BackgroundTask backgroundTask, CancellationToken c
.AddParameter("id", backgroundTask.Id.Value)
.AddParameter("state", backgroundTask.State)
.AddParameter("retry_number", backgroundTask.RetryNumber)
.AddJsonParameter("execution_metadata", backgroundTask.ExecutionMetadata, _serializerSettings)
.AddNullableJsonParameter("result", backgroundTask.Result, _serializerSettings)
.AddNullableJsonParameter("error", backgroundTask.Error, _serializerSettings)
.AddJsonParameter("execution_metadata", backgroundTask.ExecutionMetadata)
.AddNullableJsonParameter("result", backgroundTask.Result)
.AddNullableJsonParameter("error", backgroundTask.Error)
.AddParameter("scheduled_at", backgroundTask.ScheduledAt);

await command.ExecuteNonQueryAsync(cancellationToken);
Expand All @@ -170,6 +170,6 @@ public async Task UpdateAsync(BackgroundTask backgroundTask, CancellationToken c
if (value is null)
return null;

return JsonConvert.DeserializeObject(value, type, _serializerSettings) as T;
return _serializer.Deserialize<T>(value, type);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Newtonsoft.Json;
using System.Text.Json;

namespace Itmo.Dev.Platform.Common.Configurations;

public static partial class PlatformCommonConfiguration
{
public interface ISerializerStep
{
IFinalStep WithNewtonsoftSerialization(Action<JsonSerializerSettings>? configure = null);

IFinalStep WithSystemTextJsonConfiguration(Action<JsonSerializerOptions>? configure = null);
}

public interface IFinalStep;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Itmo.Dev.Platform.Common.Serialization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Text.Json;
using static Itmo.Dev.Platform.Common.Configurations.PlatformCommonConfiguration;

namespace Itmo.Dev.Platform.Common.Configurations;

internal sealed class PlatformCommonBuilder(IServiceCollection collection) : ISerializerStep, IFinalStep
{
public IFinalStep WithNewtonsoftSerialization(Action<JsonSerializerSettings>? configure = null)
{
collection.AddSingleton<IPlatformSerializer, NewtonsoftSerializer>();
collection.AddSingleton(sp => sp.GetRequiredService<IOptions<JsonSerializerSettings>>().Value);

var optionsBuilder = collection.AddOptions<JsonSerializerSettings>();

if (configure is not null)
optionsBuilder.Configure(configure);

return this;
}

public IFinalStep WithSystemTextJsonConfiguration(Action<JsonSerializerOptions>? configure = null)
{
collection.AddSingleton<IPlatformSerializer, SystemTextJsonSerializer>();
collection.AddSingleton(sp => sp.GetRequiredService<IOptions<JsonSerializerOptions>>().Value);

var optionsBuilder = collection.AddOptions<JsonSerializerOptions>();

if (configure is not null)
optionsBuilder.Configure(configure);

return this;
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Itmo.Dev.Platform.Common.Configurations;
using Itmo.Dev.Platform.Common.DateTime;
using Itmo.Dev.Platform.Common.Lifetime.Extensions;
using Itmo.Dev.Platform.Common.Options;
Expand All @@ -11,9 +12,12 @@ namespace Itmo.Dev.Platform.Common.Extensions;

public static class ServiceCollectionExtensions
{
public static IServiceCollection AddPlatform(this IServiceCollection collection)
public static IServiceCollection AddPlatform(
this IServiceCollection collection,
Func<PlatformCommonConfiguration.ISerializerStep, PlatformCommonConfiguration.IFinalStep> configuration)
{
collection.AddPlatformLifetimes();
collection.AddUtcDateTimeProvider();

collection
.AddOptions<PlatformOptions>()
Expand All @@ -28,12 +32,18 @@ public static IServiceCollection AddPlatform(this IServiceCollection collection)

collection.RemoveAll(typeof(IOptionsFactory<>));
collection.AddTransient(typeof(IOptionsFactory<>), typeof(PlatformOptionsFactory<>));


var configurator = new PlatformCommonBuilder(collection);
configuration(configurator);

return collection;
}

public static IServiceCollection AddUtcDateTimeProvider(this IServiceCollection collection)
=> collection.AddSingleton<IDateTimeProvider, UtcDateTimeProvider>();
{
collection.TryAddSingleton<IDateTimeProvider, UtcDateTimeProvider>();
return collection;
}

internal static IServiceCollection AddHostedServiceUnsafe<THostedService>(
this IServiceCollection collection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions"/>
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions"/>
<PackageReference Include="Newtonsoft.Json" />
</ItemGroup>

<ItemGroup>
Expand Down
13 changes: 13 additions & 0 deletions src/Itmo.Dev.Platform.Common/Serialization/IPlatformSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Itmo.Dev.Platform.Common.Serialization;

public interface IPlatformSerializer
{
string Serialize<T>(T value);

string Serialize<T>(T value, Type type);

T? Deserialize<T>(string value);

T? Deserialize<T>(string value, Type type)
where T : class;
}
29 changes: 29 additions & 0 deletions src/Itmo.Dev.Platform.Common/Serialization/NewtonsoftSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json;

namespace Itmo.Dev.Platform.Common.Serialization;

internal sealed class NewtonsoftSerializer : IPlatformSerializer
{
private readonly IOptions<JsonSerializerSettings> _options;

public NewtonsoftSerializer(IOptions<JsonSerializerSettings> options)
{
_options = options;
}

public string Serialize<T>(T value)
=> JsonConvert.SerializeObject(value, _options.Value);

public string Serialize<T>(T value, Type type)
=> JsonConvert.SerializeObject(value, type, _options.Value);

public T? Deserialize<T>(string value)
=> JsonConvert.DeserializeObject<T>(value, _options.Value);

public T? Deserialize<T>(string value, Type type)
where T : class
{
return JsonConvert.DeserializeObject(value, type, _options.Value) as T;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.Extensions.Options;
using System.Text.Json;

namespace Itmo.Dev.Platform.Common.Serialization;

internal sealed class SystemTextJsonSerializer : IPlatformSerializer
{
private readonly IOptions<JsonSerializerOptions> _options;

public SystemTextJsonSerializer(IOptions<JsonSerializerOptions> options)
{
_options = options;
}

public string Serialize<T>(T value)
=> JsonSerializer.Serialize(value, _options.Value);

public string Serialize<T>(T value, Type type)
=> JsonSerializer.Serialize(value, type, _options.Value);

public T? Deserialize<T>(string value)
=> JsonSerializer.Deserialize<T>(value, _options.Value);

public T? Deserialize<T>(string value, Type type)
where T : class
{
return JsonSerializer.Deserialize(value, type, _options.Value) as T;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ protected override async Task ExecuteAsync(CancellationToken cancellationToken)
.AddOptions<MessagePersistencePostgresOptions>()
.Configure(o => persistenceOptions.Value.ApplyTo(o));

collection.AddPlatform();
collection.AddPlatform(x => x.WithSystemTextJsonConfiguration());

collection.AddPlatformPersistence(
persistence => persistence.UsePostgres(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static void AddPlatformObservability(
configuration.Invoke(configurator);
}

collection.AddPlatform();
collection.AddPlatform(x => x.WithSystemTextJsonConfiguration());
collection.AddLogging(x => x.AddConsole().SetMinimumLevel(LogLevel.Trace));

collection.AddSentryPlugins();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ namespace Itmo.Dev.Platform.Persistence.Abstractions.Commands;
public interface IPersistenceCommand : IAsyncDisposable
{
ValueTask<DbDataReader> ExecuteReaderAsync(CancellationToken cancellationToken);

ValueTask<int> ExecuteNonQueryAsync(CancellationToken cancellationToken);

IPersistenceCommand AddParameter(DbParameter parameter);

IPersistenceCommand AddParameter<T>(string parameterName, T value);

[OverloadResolutionPriority(int.MaxValue)]
Expand All @@ -27,24 +27,12 @@ IPersistenceCommand AddMultiArrayStringParameter(
string parameterName,
IEnumerable<IEnumerable<string>> values);

IPersistenceCommand AddJsonParameter<T>(
string parameterName,
T value,
JsonSerializerSettings? serializerSettings = null);
IPersistenceCommand AddJsonParameter<T>(string parameterName, T value);

IPersistenceCommand AddNullableJsonParameter<T>(
string parameterName,
T? value,
JsonSerializerSettings? serializerSettings = null)
IPersistenceCommand AddNullableJsonParameter<T>(string parameterName, T? value)
where T : class;

IPersistenceCommand AddJsonArrayParameter<T>(
string parameterName,
IEnumerable<T> values,
JsonSerializerSettings? serializerSettings = null);

IPersistenceCommand AddJsonArrayParameter(
string parameterName,
IEnumerable<string> values);
IPersistenceCommand AddJsonArrayParameter<T>(string parameterName, IEnumerable<T> values);

}
IPersistenceCommand AddJsonArrayParameter(string parameterName, IEnumerable<string> values);
}
Loading
Loading