diff --git a/TeachingRecordSystem/Directory.Packages.props b/TeachingRecordSystem/Directory.Packages.props
index 36f494c00..d80fdeb3d 100644
--- a/TeachingRecordSystem/Directory.Packages.props
+++ b/TeachingRecordSystem/Directory.Packages.props
@@ -63,6 +63,7 @@
+
@@ -86,4 +87,4 @@
-
\ No newline at end of file
+
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Services/DqtReporting/DqtReportingService.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Services/DqtReporting/DqtReportingService.cs
index 98ec31e32..6e1e4a580 100644
--- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Services/DqtReporting/DqtReportingService.cs
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Services/DqtReporting/DqtReportingService.cs
@@ -10,6 +10,7 @@
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
+using Polly;
using TeachingRecordSystem.Core.Dqt;
using TeachingRecordSystem.Core.Dqt.Queries;
using TeachingRecordSystem.Core.Services.CrmEntityChanges;
@@ -27,6 +28,15 @@ public partial class DqtReportingService : BackgroundService
private const int MaxUpsertBatchSize = 100;
private const int MaxEntityTypesToProcessConcurrently = 10;
+ private static readonly ResiliencePipeline _resiliencePipeline = new ResiliencePipelineBuilder()
+ .AddRetry(new Polly.Retry.RetryStrategyOptions()
+ {
+ BackoffType = DelayBackoffType.Exponential,
+ Delay = TimeSpan.FromSeconds(30),
+ MaxRetryAttempts = 3
+ })
+ .Build();
+
private readonly DqtReportingOptions _options;
private readonly ICrmEntityChangesService _crmEntityChangesService;
private readonly ICrmQueryDispatcher _crmQueryDispatcher;
@@ -61,7 +71,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
- await ProcessChanges(stoppingToken);
+ await _resiliencePipeline.ExecuteAsync(async ct => await ProcessChanges(ct), stoppingToken);
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
{
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Services/TrsDataSync/TrsDataSyncService.cs b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Services/TrsDataSync/TrsDataSyncService.cs
index 25e211aca..a129ad729 100644
--- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/Services/TrsDataSync/TrsDataSyncService.cs
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/Services/TrsDataSync/TrsDataSyncService.cs
@@ -4,6 +4,7 @@
using Microsoft.Extensions.Options;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
+using Polly;
using TeachingRecordSystem.Core.Services.CrmEntityChanges;
namespace TeachingRecordSystem.Core.Services.TrsDataSync;
@@ -17,6 +18,15 @@ public class TrsDataSyncService(
public const string CrmClientName = "TrsDataSync";
private const string ChangesKeyPrefix = "TrsDataSync";
+ private static readonly ResiliencePipeline _resiliencePipeline = new ResiliencePipelineBuilder()
+ .AddRetry(new Polly.Retry.RetryStrategyOptions()
+ {
+ BackoffType = DelayBackoffType.Exponential,
+ Delay = TimeSpan.FromSeconds(30),
+ MaxRetryAttempts = 3
+ })
+ .Build();
+
private const int PageSize = 1000;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
@@ -27,7 +37,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
- await ProcessChanges(stoppingToken);
+ await _resiliencePipeline.ExecuteAsync(async ct => await ProcessChanges(ct), stoppingToken);
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
{
diff --git a/TeachingRecordSystem/src/TeachingRecordSystem.Core/TeachingRecordSystem.Core.csproj b/TeachingRecordSystem/src/TeachingRecordSystem.Core/TeachingRecordSystem.Core.csproj
index c0c3df969..ebfde4d4b 100644
--- a/TeachingRecordSystem/src/TeachingRecordSystem.Core/TeachingRecordSystem.Core.csproj
+++ b/TeachingRecordSystem/src/TeachingRecordSystem.Core/TeachingRecordSystem.Core.csproj
@@ -74,6 +74,7 @@
+