Add Bookmark Persister and Bookmark Updater

The code introduces BookmarkPersister for processing bookmarks as part of the workflow runtime. This refactoring improves readability and maintainability by separating the bookmark persisting logic from the PersistBookmarkMiddleware class. A new class, BookmarkUpdater, is also added to handle updating of bookmarks. Changes also include adjustments to several other classes for improved functionality and code consistency.
This commit is contained in:
Sipke Schoorstra 2023-12-18 16:05:12 +01:00
parent ae821b4494
commit f575d38dcc
4 changed files with 95 additions and 0 deletions

View file

@ -0,0 +1,16 @@
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Helpers;
using Elsa.Workflows.Core.Models;
namespace Elsa.Workflows.Runtime.Contracts;
/// <summary>
/// Persists bookmarks and raises events.
/// </summary>
public interface IBookmarksPersister
{
/// <summary>
/// Persists bookmarks and raises events.
/// </summary>
Task PersistBookmarksAsync(WorkflowExecutionContext context, Diff<Bookmark> diff);
}

View file

@ -0,0 +1,8 @@
using Elsa.Workflows.Runtime.Requests;
namespace Elsa.Workflows.Runtime.Contracts;
public interface IBookmarkUpdater
{
Task UpdateBookmarksAsync(UpdateBookmarksRequest request, CancellationToken cancellationToken = default);
}

View file

@ -0,0 +1,36 @@
using Elsa.Mediator;
using Elsa.Mediator.Contracts;
using Elsa.Workflows.Core;
using Elsa.Workflows.Core.Helpers;
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Runtime.Contracts;
using Elsa.Workflows.Runtime.Notifications;
using Elsa.Workflows.Runtime.Requests;
namespace Elsa.Workflows.Runtime.Services;
/// <inheritdoc />
public class BookmarksPersister(IBookmarkUpdater bookmarkUpdater, INotificationSender notificationSender) : IBookmarksPersister
{
/// <inheritdoc />
public async Task PersistBookmarksAsync(WorkflowExecutionContext context, Diff<Bookmark> diff)
{
var cancellationToken = context.CancellationTokens.SystemCancellationToken;
var updateBookmarksContext = new UpdateBookmarksRequest(context.Id, diff, context.CorrelationId);
await bookmarkUpdater.UpdateBookmarksAsync(updateBookmarksContext, cancellationToken);
// Publish domain event.
await notificationSender.SendAsync(new WorkflowBookmarksIndexed(context, new IndexedWorkflowBookmarks(context.Id, diff.Added, diff.Removed, diff.Unchanged)), cancellationToken);
// Notify all interested activities that the bookmarks have been persisted.
var activityExecutionContexts = context.ActivityExecutionContexts.Where(x => x.Activity is IBookmarksPersistedHandler && x.Bookmarks.Any()).ToList();
foreach (var activityExecutionContext in activityExecutionContexts)
await ((IBookmarksPersistedHandler)activityExecutionContext.Activity).BookmarksPersistedAsync(activityExecutionContext);
// Publish domain event.
await notificationSender.SendAsync(new WorkflowBookmarksPersisted(context, diff), NotificationStrategy.Background, cancellationToken);
}
}

View file

@ -0,0 +1,35 @@
using Elsa.Workflows.Core.Models;
using Elsa.Workflows.Runtime.Contracts;
using Elsa.Workflows.Runtime.Entities;
using Elsa.Workflows.Runtime.Filters;
using Elsa.Workflows.Runtime.Requests;
namespace Elsa.Workflows.Runtime.Services;
/// <inheritdoc />
public class BookmarkUpdater(IBookmarkManager bookmarkManager, IBookmarkStore bookmarkStore) : IBookmarkUpdater
{
/// <inheritdoc />
public async Task UpdateBookmarksAsync(UpdateBookmarksRequest request, CancellationToken cancellationToken = default)
{
var instanceId = request.WorkflowInstanceId;
await RemoveBookmarksAsync(instanceId, request.Diff.Removed, cancellationToken);
await StoreBookmarksAsync(instanceId, request.Diff.Added, request.CorrelationId, cancellationToken);
}
private async Task RemoveBookmarksAsync(string workflowInstanceId, IEnumerable<Bookmark> bookmarks, CancellationToken cancellationToken)
{
var matchingHashes = bookmarks.Select(x => x.Hash).ToList();
var filter = new BookmarkFilter { Hashes = matchingHashes, WorkflowInstanceId = workflowInstanceId };
await bookmarkManager.DeleteManyAsync(filter, cancellationToken);
}
private async Task StoreBookmarksAsync(string workflowInstanceId, IEnumerable<Bookmark> bookmarks, string? correlationId, CancellationToken cancellationToken)
{
foreach (var bookmark in bookmarks)
{
var storedBookmark = new StoredBookmark(bookmark.Id, bookmark.Name, bookmark.Hash, workflowInstanceId, bookmark.CreatedAt, bookmark.ActivityInstanceId, correlationId, bookmark.Payload);
await bookmarkStore.SaveAsync(storedBookmark, cancellationToken);
}
}
}