Skip to content

Commit

Permalink
Merge pull request #73 from atidev/extend_serializers_support
Browse files Browse the repository at this point in the history
Поддержать расширение common сторонними сериализаторами
  • Loading branch information
AlexFate committed Mar 5, 2024
2 parents b132482 + 317179c commit 0f48984
Show file tree
Hide file tree
Showing 28 changed files with 1,416 additions and 1,171 deletions.
4 changes: 2 additions & 2 deletions ATI.Services.Common/ATI.Services.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Dapper" Version="2.0.30" />
<PackageReference Include="HtmlSanitizer" Version="8.0.692" />
<PackageReference Include="HtmlSanitizer" Version="8.0.843" />
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.2" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.3" />
<PackageReference Include="NLog" Version="4.7.6" />
<PackageReference Include="NLog.DiagnosticSource" Version="1.3.0" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.3" />
<PackageReference Include="Npgsql" Version="7.0.4" />
<PackageReference Include="Npgsql" Version="7.0.6" />
<PackageReference Include="Polly" Version="7.2.3" />
<PackageReference Include="prometheus-net" Version="8.2.1" />
<PackageReference Include="StackExchange.Redis" Version="2.2.50" />
Expand Down
1 change: 0 additions & 1 deletion ATI.Services.Common/Behaviors/CommonBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;


namespace ATI.Services.Common.Behaviors
{
public static class CommonBehavior
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;


namespace ATI.Services.Common.Behaviors.OperationBuilder
{
public class ActionBuilder : BaseActionBuilder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Threading.Tasks;


namespace ATI.Services.Common.Behaviors.OperationBuilder
{
public abstract class BaseFunctionBuilder<T> : BaseActionBuilder
Expand Down
1 change: 0 additions & 1 deletion ATI.Services.Common/Behaviors/OperationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Net;
using JetBrains.Annotations;


namespace ATI.Services.Common.Behaviors
{
[PublicAPI]
Expand Down
8 changes: 0 additions & 8 deletions ATI.Services.Common/Caching/KeyExistResult.cs

This file was deleted.

13 changes: 13 additions & 0 deletions ATI.Services.Common/Caching/Redis/Abstractions/IRedisSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using StackExchange.Redis;

namespace ATI.Services.Common.Caching.Redis.Abstractions;

public interface IRedisSerializer
{
public RedisValue Serialize<TIn>(TIn value);
public RedisValue Serialize(object value, Type type);

public T Deserialize<T>(RedisValue value);
object Deserialize(RedisValue value, Type type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using ATI.Services.Common.Serializers;
using StackExchange.Redis;

namespace ATI.Services.Common.Caching.Redis.Abstractions;

public sealed class RedisBinarySerializer : IRedisSerializer
{
private readonly IBinarySerializer _serializer;

public RedisBinarySerializer(IBinarySerializer serializer)
{
_serializer = serializer;
}

public RedisValue Serialize<TIn>(TIn value) => _serializer.Serialize(value);

public RedisValue Serialize(object value, Type type) => _serializer.Serialize(value, type);

public T Deserialize<T>(RedisValue value) => _serializer.Deserialize<T>(value);
public object Deserialize(RedisValue value, Type type) => _serializer.Deserialize(value, type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using ATI.Services.Common.Serializers;
using StackExchange.Redis;

namespace ATI.Services.Common.Caching.Redis.Abstractions;

public sealed class RedisStringSerializer : IRedisSerializer
{
private readonly ISerializer<string> _serializer;

public RedisStringSerializer(ISerializer serializer)
{
_serializer = serializer;
}

public RedisValue Serialize<TIn>(TIn value) => _serializer.Serialize(value);

public RedisValue Serialize(object value, Type type) => _serializer.Serialize(value, type);

public T Deserialize<T>(RedisValue value) => _serializer.Deserialize<T>(value);
public object Deserialize(RedisValue value, Type type) => _serializer.Deserialize(value, type);
}
117 changes: 57 additions & 60 deletions ATI.Services.Common/Caching/Redis/BaseRedisCache.cs
Original file line number Diff line number Diff line change
@@ -1,86 +1,83 @@
using System;
using System.Threading.Tasks;
using ATI.Services.Common.Behaviors;
using ATI.Services.Common.Caching.Redis.Abstractions;
using ATI.Services.Common.Logging;
using ATI.Services.Common.Serializers;
using NLog;
using Polly.CircuitBreaker;
using Polly.Timeout;
using Polly.Wrap;
using StackExchange.Redis;

namespace ATI.Services.Common.Caching.Redis
namespace ATI.Services.Common.Caching.Redis;

public abstract class BaseRedisCache
{
public abstract class BaseRedisCache
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
protected IRedisSerializer Serializer;
protected RedisOptions Options;

protected async Task<OperationResult> ExecuteAsync(
Func<Task> func,
object context,
AsyncCircuitBreakerPolicy circuitBreakerPolicy,
AsyncPolicyWrap policy)
{
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
protected readonly ISerializer Serializer;
try
{
if (circuitBreakerPolicy.CircuitState == CircuitState.Open)
{
return new OperationResult(ActionStatus.InternalOptionalServerUnavailable);
}

protected RedisOptions Options;
await policy.ExecuteAsync(func);

protected BaseRedisCache(ISerializer serializer)
return OperationResult.Ok;
}
catch (TimeoutRejectedException ex)
{
Serializer = serializer;
Logger.ErrorWithObject(ex,
new { DelegateName = func?.Method.Name, ReturnType = func?.Method.ReturnType.Name, Context = context });
return new OperationResult(ActionStatus.Timeout);
}

protected async Task<OperationResult> ExecuteAsync(
Func<Task> func,
object context,
AsyncCircuitBreakerPolicy circuitBreakerPolicy,
AsyncPolicyWrap policy)
catch (Exception ex)
{
try
{
if (circuitBreakerPolicy.CircuitState == CircuitState.Open)
{
return new OperationResult(ActionStatus.InternalOptionalServerUnavailable);
}

await policy.ExecuteAsync(func);

return OperationResult.Ok;
}
catch (TimeoutRejectedException ex)
{
Logger.ErrorWithObject(ex, new { DelegateName = func?.Method.Name, ReturnType = func?.Method.ReturnType.Name, Context = context });
return new OperationResult(ActionStatus.Timeout);
}
catch (Exception ex)
{
Logger.ErrorWithObject(ex, new { DelegateName = func?.Method.Name, ReturnType = func?.Method.ReturnType.Name, Context = context });
return new OperationResult(ActionStatus.InternalOptionalServerUnavailable);
}
Logger.ErrorWithObject(ex,
new { DelegateName = func?.Method.Name, ReturnType = func?.Method.ReturnType.Name, Context = context });
return new OperationResult(ActionStatus.InternalOptionalServerUnavailable);
}
}

protected async Task<OperationResult<T>> ExecuteAsync<T>(
Func<Task<T>> func,
object context,
AsyncCircuitBreakerPolicy circuitBreakerPolicy,
AsyncPolicyWrap policy)
protected async Task<OperationResult<T>> ExecuteAsync<T>(
Func<Task<T>> func,
object context,
AsyncCircuitBreakerPolicy circuitBreakerPolicy,
AsyncPolicyWrap policy)
{
try
{
try
{
if (circuitBreakerPolicy.CircuitState == CircuitState.Open)
{
return new OperationResult<T>(ActionStatus.InternalOptionalServerUnavailable);
}

var result = await policy.ExecuteAsync(func);

return result == null || result is RedisValue resultAsRedisValue && resultAsRedisValue.IsNull
? new OperationResult<T>(ActionStatus.NotFound)
: new OperationResult<T>(result);
}
catch (TimeoutRejectedException ex)
if (circuitBreakerPolicy.CircuitState == CircuitState.Open)
{
Logger.ErrorWithObject(ex, new { DelegateName = func?.Method.Name, ReturnType = func?.Method.ReturnType.Name, Context = context });
return new OperationResult<T>(ActionStatus.Timeout);
}
catch (Exception ex)
{
Logger.ErrorWithObject(ex, new { DelegateName = func?.Method.Name, ReturnType = func?.Method.ReturnType.Name, Context = context });
return new OperationResult<T>(ActionStatus.InternalOptionalServerUnavailable);
}

var result = await policy.ExecuteAsync(func);

return result == null || result is RedisValue resultAsRedisValue && resultAsRedisValue.IsNull
? new OperationResult<T>(ActionStatus.NotFound)
: new OperationResult<T>(result);
}
catch (TimeoutRejectedException ex)
{
Logger.ErrorWithObject(ex,
new { DelegateName = func?.Method.Name, ReturnType = func?.Method.ReturnType.Name, Context = context });
return new OperationResult<T>(ActionStatus.Timeout);
}
catch (Exception ex)
{
Logger.ErrorWithObject(ex,
new { DelegateName = func?.Method.Name, ReturnType = func?.Method.ReturnType.Name, Context = context });
return new OperationResult<T>(ActionStatus.InternalOptionalServerUnavailable);
}
}
}
Loading

0 comments on commit 0f48984

Please sign in to comment.