-
Notifications
You must be signed in to change notification settings - Fork 51
/
LogChangesChangedEventHandler.cs
51 lines (45 loc) · 2.36 KB
/
LogChangesChangedEventHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using VirtoCommerce.CatalogModule.Core.Events;
using VirtoCommerce.Platform.Core.ChangeLog;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.Events;
namespace VirtoCommerce.CatalogModule.Data.Handlers
{
public class LogChangesChangedEventHandler : IEventHandler<ProductChangedEvent>, IEventHandler<CategoryChangedEvent>
{
private readonly IChangeLogService _changeLogService;
public LogChangesChangedEventHandler(IChangeLogService changeLogService)
{
_changeLogService = changeLogService;
}
public virtual Task Handle(ProductChangedEvent @event)
{
InnerHandle(@event);
return Task.CompletedTask;
}
public virtual Task Handle(CategoryChangedEvent @event)
{
InnerHandle(@event);
return Task.CompletedTask;
}
protected virtual void InnerHandle<T>(GenericChangedEntryEvent<T> @event) where T : IEntity
{
var logOperations = @event.ChangedEntries.Select(x => AbstractTypeFactory<OperationLog>.TryCreateInstance().FromChangedEntry(x)).ToArray();
//Background task is used here for performance reasons
BackgroundJob.Enqueue(() => LogEntityChangesInBackground(logOperations));
}
[DisableConcurrentExecution(10)]
// "DisableConcurrentExecutionAttribute" prevents to start simultaneous job payloads.
// Should have short timeout, because this attribute implemented by following manner: newly started job falls into "processing" state immediately.
// Then it tries to receive job lock during timeout. If the lock received, the job starts payload.
// When the job is awaiting desired timeout for lock release, it stucks in "processing" anyway. (Therefore, you should not to set long timeouts (like 24*60*60), this will cause a lot of stucked jobs and performance degradation.)
// Then, if timeout is over and the lock NOT acquired, the job falls into "scheduled" state (this is default fail-retry scenario).
// Failed job goes to "Failed" state (by default) after retries exhausted.
public void LogEntityChangesInBackground(OperationLog[] operationLogs)
{
_changeLogService.SaveChangesAsync(operationLogs).GetAwaiter().GetResult();
}
}
}