< Summary

Line coverage
80%
Covered lines: 241
Uncovered lines: 57
Coverable lines: 298
Total lines: 941
Line coverage: 80.8%
Branch coverage
79%
Covered branches: 83
Total branches: 104
Branch coverage: 79.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: CanCancelActivity()50%22100%
File 1: CancelActivityAsync()0%620%
File 1: CancelChildActivitiesAsync()0%620%
File 2: CompleteActivityAsync()66.66%141277.27%
File 2: CompleteActivityWithOutcomesAsync(...)100%11100%
File 2: CompleteCompositeAsync()100%210%
File 3: .ctor(...)100%44100%
File 3: get_Id()100%11100%
File 3: get_StartedAt()100%11100%
File 3: get_Tag()100%11100%
File 3: get_CompletedAt()100%11100%
File 3: get_IsCompleted()100%22100%
File 3: get_IsExecuting()100%11100%
File 3: get_AggregateFaultCount()100%11100%
File 3: get_WorkflowExecutionContext()100%11100%
File 3: get_ParentActivityExecutionContext()100%11100%
File 3: set_ParentActivityExecutionContext(...)100%22100%
File 3: get_ExpressionExecutionContext()100%11100%
File 3: get_Variables()83.33%1212100%
File 3: get_DynamicVariables()100%11100%
File 3: get_Activity()100%11100%
File 3: get_ActivityDescriptor()100%11100%
File 3: get_CancellationToken()100%11100%
File 3: get_Status()100%11100%
File 3: set_Status(...)100%22100%
File 3: EnterExecution()100%11100%
File 3: TransitionTo(...)100%11100%
File 3: get_Exception()100%11100%
File 3: set_Exception(...)100%11100%
File 3: get_Properties()100%11100%
File 3: get_TransientProperties()100%11100%
File 3: get_Metadata()100%11100%
File 3: get_ActivityNode()100%11100%
File 3: get_NodeId()100%11100%
File 3: get_Children()100%11100%
File 3: get_Bookmarks()100%11100%
File 3: get_NewBookmarks()100%11100%
File 3: get_ExecutionCount()100%210%
File 3: get_WorkflowInput()100%11100%
File 3: get_ActivityInput()100%11100%
File 3: get_JournalData()100%11100%
File 3: get_ActivityState()100%11100%
File 3: get_IsDirty()100%11100%
File 3: ScheduleActivityAsync(...)100%22100%
File 3: ScheduleActivityAsync()100%11100%
File 3: ScheduleActivityAsync()100%11100%
File 3: ScheduleActivityAsync()100%210%
File 3: ScheduleActivitiesAsync()100%210%
File 3: ScheduleActivities(...)50%22100%
File 3: ScheduleActivities()100%22100%
File 3: CreateBookmarks(...)100%22100%
File 3: AddBookmarks(...)100%210%
File 3: AddBookmark(...)100%11100%
File 3: CreateBookmark(...)100%11100%
File 3: CreateBookmark(...)100%210%
File 3: CreateBookmark(...)100%210%
File 3: CreateBookmark(...)100%11100%
File 3: CreateBookmark(...)100%2424100%
File 3: ClearBookmarks()100%11100%
File 3: GetProperty(...)100%22100%
File 3: GetProperty(...)100%22100%
File 3: SetProperty(...)100%11100%
File 3: UpdateProperty(...)100%11100%
File 3: RemoveProperty(...)100%210%
File 3: GetMetadata(...)0%620%
File 3: GetMetadata(...)100%22100%
File 3: SetMetadata(...)100%11100%
File 3: UpdateMetadata(...)100%210%
File 3: RemoveMetadata(...)100%210%
File 3: GetRequiredService()100%11100%
File 3: GetRequiredService(...)100%11100%
File 3: GetOrCreateService()100%210%
File 3: GetOrCreateService(...)100%210%
File 3: GetService()100%11100%
File 3: GetServices()100%11100%
File 3: GetService(...)100%210%
File 3: Get(...)100%22100%
File 3: Get(...)0%620%
File 3: Get(...)100%22100%
File 3: Get(...)50%22100%
File 3: Get(...)100%22100%
File 3: TryGet(...)50%2266.66%
File 3: Set(...)100%11100%
File 3: Set(...)100%11100%
File 3: Set(...)100%11100%
File 3: ClearCompletionCallbacks()100%11100%
File 3: Taint()100%22100%
File 3: ClearTaint()100%22100%
File 3: IncrementExecutionCount()100%11100%
File 3: GetMemoryBlock(...)50%22100%
File 3: System.IDisposable.Dispose()100%210%
File 4: AddExecutionLogEntry(...)100%44100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Contexts/ActivityExecutionContext.Cancel.cs

#LineLine coverage
 1using Elsa.Extensions;
 2using Elsa.Mediator.Contracts;
 3using Elsa.Workflows.Notifications;
 4using Elsa.Workflows.Signals;
 5
 6namespace Elsa.Workflows;
 7
 8public partial class ActivityExecutionContext
 9{
 10    private readonly INotificationSender _publisher;
 11
 12    private bool CanCancelActivity()
 13    {
 264814        return Status is not ActivityStatus.Canceled and not ActivityStatus.Completed;
 15    }
 16
 17    private async Task CancelActivityAsync()
 18    {
 019        if(!CanCancelActivity())
 020            return;
 21
 022        TransitionTo(ActivityStatus.Canceled);
 023        ClearBookmarks();
 024        ClearCompletionCallbacks();
 025        WorkflowExecutionContext.Bookmarks.RemoveWhere(x => x.ActivityNodeId == NodeId);
 026        AddExecutionLogEntry("Canceled");
 027        await this.SendSignalAsync(new CancelSignal());
 028        await CancelChildActivitiesAsync();
 29
 30        // ReSharper disable once MethodSupportsCancellation
 031        await _publisher.SendAsync(new ActivityCancelled(this));
 032    }
 33
 34    private async Task CancelChildActivitiesAsync()
 35    {
 036        var childContexts = WorkflowExecutionContext.ActivityExecutionContexts.Where(x => x.ParentActivityExecutionConte
 37
 038        foreach (var childContext in childContexts)
 039            await childContext.CancelActivityAsync();
 040    }
 41}

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Contexts/ActivityExecutionContext.Complete.cs

#LineLine coverage
 1using Elsa.Extensions;
 2using Elsa.Mediator.Contracts;
 3using Elsa.Workflows.Activities.Flowchart.Models;
 4using Elsa.Workflows.Signals;
 5
 6namespace Elsa.Workflows;
 7
 8public partial class ActivityExecutionContext
 9{
 10    /// <summary>
 11    /// Complete the current activity. This should only be called by activities that explicitly suppress automatic-compl
 12    /// </summary>
 13    public async ValueTask CompleteActivityAsync(object? result = null)
 14    {
 333615        var outcomes = result as Outcomes;
 16
 17        // If the activity is executing in the background, simply capture the result and return.
 333618        if (this.GetIsBackgroundExecution())
 19        {
 020            if (outcomes != null)
 021                this.SetBackgroundOutcomes(outcomes.Names);
 22            else
 023                this.SetBackgroundCompletion();
 024            return;
 25        }
 26
 27        // If the activity is not running, do nothing.
 333628        if (Status != ActivityStatus.Running)
 729            return;
 30
 31        // Cancel any non-completed child activities.
 597732        var childContexts = Children.Where(x => x.CanCancelActivity()).ToList();
 33
 665834        foreach (var childContext in childContexts)
 035            await childContext.CancelActivityAsync();
 36
 37        // Mark the activity as complete.
 332938        TransitionTo(ActivityStatus.Completed);
 39
 40        // Record the outcomes, if any.
 332941        if (outcomes != null)
 10442            JournalData["Outcomes"] = outcomes.Names;
 43
 44        // Add an execution log entry.
 332945        AddExecutionLogEntry("Completed");
 46
 47        // Send a signal.
 332948        await this.SendSignalAsync(new ActivityCompleted(result));
 49
 50        // Clear bookmarks.
 332951        ClearBookmarks();
 335952        WorkflowExecutionContext.Bookmarks.RemoveWhere(x => x.ActivityInstanceId == Id);
 53
 54        // Remove completion callbacks.
 332955        ClearCompletionCallbacks();
 56
 57        // Remove all associated variables, unless this is the root context - in which case we want to keep the variable
 332958        if (ParentActivityExecutionContext != null)
 59        {
 269560            var variablePersistenceManager = GetRequiredService<IVariablePersistenceManager>();
 269561            await variablePersistenceManager.DeleteVariablesAsync(this);
 62        }
 63
 64        // Update the completed at timestamp.
 332965        CompletedAt = WorkflowExecutionContext.SystemClock.UtcNow;
 333666    }
 67
 68    /// <summary>
 69    /// Complete the current activity with the specified outcomes.
 70    /// </summary>
 71    public ValueTask CompleteActivityWithOutcomesAsync(params string[] outcomes)
 72    {
 9973        return CompleteActivityAsync(new Outcomes(outcomes));
 74    }
 75
 76    /// <summary>
 77    /// Complete the current composite activity with the specified outcome.
 78    /// </summary>
 79    public async ValueTask CompleteCompositeAsync(params string[] outcomes)
 80    {
 081        await this.SendSignalAsync(new CompleteCompositeSignal(new Outcomes(outcomes)));
 082    }
 83}

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Contexts/ActivityExecutionContext.cs

#LineLine coverage
 1using System.Runtime.CompilerServices;
 2using Elsa.Common;
 3using Elsa.Expressions.Helpers;
 4using Elsa.Expressions.Models;
 5using Elsa.Extensions;
 6using Elsa.Mediator.Contracts;
 7using Elsa.Workflows.Memory;
 8using Elsa.Workflows.Models;
 9using Elsa.Workflows.Options;
 10using JetBrains.Annotations;
 11
 12namespace Elsa.Workflows;
 13
 14/// <summary>
 15/// Represents the context of an activity execution.
 16/// </summary>
 17[PublicAPI]
 18public partial class ActivityExecutionContext : IExecutionContext, IDisposable
 19{
 20    private readonly ISystemClock _systemClock;
 21    private ActivityStatus _status;
 22    private Exception? _exception;
 23    private long _executionCount;
 24    private ActivityExecutionContext? _parentActivityExecutionContext;
 25
 26    // Bookmarks created during the lifetime of this activity.
 375227    private List<Bookmark> _newBookmarks = [];
 28
 29    /// <summary>
 30    /// Initializes a new instance of the <see cref="ActivityExecutionContext"/> class.
 31    /// </summary>
 375232    public ActivityExecutionContext(
 375233        string id,
 375234        WorkflowExecutionContext workflowExecutionContext,
 375235        ActivityExecutionContext? parentActivityExecutionContext,
 375236        IActivity activity,
 375237        ActivityDescriptor activityDescriptor,
 375238        DateTimeOffset startedAt,
 375239        object? tag,
 375240        ISystemClock systemClock,
 375241        CancellationToken cancellationToken)
 42    {
 375243        _systemClock = systemClock;
 375244        Properties = new ChangeTrackingDictionary<string, object>(Taint);
 375245        Metadata = new ChangeTrackingDictionary<string, object>(Taint);
 375246        ActivityState = new ChangeTrackingDictionary<string, object>(Taint);
 375247        ActivityInput = new ChangeTrackingDictionary<string, object>(Taint);
 375248        WorkflowExecutionContext = workflowExecutionContext;
 375249        ParentActivityExecutionContext = parentActivityExecutionContext;
 375250        var expressionExecutionContextProps = ExpressionExecutionContextExtensions.CreateActivityExecutionContextPropert
 375251        expressionExecutionContextProps[ExpressionExecutionContextExtensions.ActivityKey] = activity;
 375252        ExpressionExecutionContext = new(workflowExecutionContext.ServiceProvider, new(), parentActivityExecutionContext
 375253        Activity = activity;
 375254        ActivityDescriptor = activityDescriptor;
 375255        StartedAt = startedAt;
 375256        Status = ActivityStatus.Pending;
 375257        Tag = tag;
 375258        CancellationToken = cancellationToken;
 375259        Id = id;
 375260        _publisher = GetRequiredService<INotificationSender>();
 375261    }
 62
 63    /// <summary>
 64    /// The ID of the current activity execution context.
 65    /// </summary>
 3076466    public string Id { get; set; }
 67
 68    /// <summary>
 69    /// The time at which the activity execution context was created.
 70    /// </summary>
 784971    public DateTimeOffset StartedAt { get; set; }
 72
 73    /// <summary>
 74    /// An optional tag to associate with the activity execution.
 75    /// </summary>
 723176    public object? Tag { get; set; }
 77
 78    /// <summary>
 79    /// The time at which the activity execution context was completed.
 80    /// </summary>
 742681    public DateTimeOffset? CompletedAt { get; set; }
 82
 83    /// <summary>
 84    /// Returns true if the activity execution context has completed.
 85    /// </summary>
 1311186    public bool IsCompleted => Status is ActivityStatus.Completed or ActivityStatus.Canceled;
 87
 88    /// <summary>
 89    /// Gets or sets a value indicating whether the activity is actively executing.
 90    /// </summary>
 91    /// <remarks>
 92    /// This flag is set to <c>true</c> immediately before the activity begins execution
 93    /// and is set to <c>false</c> once the execution is completed.
 94    /// It can be used to determine if an activity was in-progress in case of unexpected
 95    /// application termination, allowing the system to retry execution upon restarting.
 96    /// </remarks>
 721297    public bool IsExecuting { get; set; }
 98
 99    /// <summary>
 100    /// The number of faults encountered during the execution of the activity and its descendants.
 101    /// </summary>
 4190102    public int AggregateFaultCount { get; set; }
 103
 104    /// <summary>
 105    /// The workflow execution context.
 106    /// </summary>
 163542107    public WorkflowExecutionContext WorkflowExecutionContext { get; }
 108
 109    /// <summary>
 110    /// The parent activity execution context, if any.
 111    /// </summary>
 112    public ActivityExecutionContext? ParentActivityExecutionContext
 113    {
 60803114        get => _parentActivityExecutionContext;
 115        internal set
 116        {
 3844117            _parentActivityExecutionContext = value;
 3844118            _parentActivityExecutionContext?.Children.Add(this);
 2831119        }
 120    }
 121
 122    /// <summary>
 123    /// The expression execution context.
 124    /// </summary>
 44647125    public ExpressionExecutionContext ExpressionExecutionContext { get; }
 126
 127    /// <inheritdoc />
 128    public IEnumerable<Variable> Variables
 129    {
 130        get
 131        {
 6220132            var containerVariables = (Activity as IVariableContainer)?.Variables ?? Enumerable.Empty<Variable>();
 6220133            var dynamicVariables = DynamicVariables;
 6220134            var mergedVariables = new Dictionary<string, Variable>();
 135
 12718136            foreach (var containerVariable in containerVariables)
 137            {
 139138                var name = !string.IsNullOrEmpty(containerVariable.Name) ? containerVariable.Name : containerVariable.Id
 139139                mergedVariables[name] = containerVariable;
 140            }
 141
 12810142            foreach (var dynamicVariable in dynamicVariables)
 143            {
 185144                var name = !string.IsNullOrEmpty(dynamicVariable.Name) ? dynamicVariable.Name : dynamicVariable.Id;
 185145                mergedVariables[name] = dynamicVariable;
 146            }
 6220147            return mergedVariables.Values;
 148        }
 149    }
 150
 151    /// <summary>
 152    /// A list of variables that are dynamically added to the activity execution context.
 153    /// </summary>
 10906154    public ICollection<Variable> DynamicVariables { get; set; } = new List<Variable>();
 155
 156    /// <summary>
 157    /// The currently executing activity.
 158    /// </summary>
 196240159    public IActivity Activity { get; set; }
 160
 161    /// <summary>
 162    /// The activity descriptor.
 163    /// </summary>
 25368164    public ActivityDescriptor ActivityDescriptor { get; }
 165
 166    /// <summary>
 167    /// A cancellation token to use when invoking asynchronous operations.
 168    /// </summary>
 33625169    public CancellationToken CancellationToken { get; }
 170
 171    /// <summary>
 172    /// The current status of the activity.
 173    /// </summary>
 174    public ActivityStatus Status
 175    {
 39092176        get => _status;
 177        private set
 178        {
 10841179            if (value == _status)
 3788180                return;
 181
 7053182            _status = value;
 7053183            Taint();
 7053184        }
 185    }
 186
 187    public IDisposable EnterExecution()
 188    {
 3226189        return new WorkflowExecutionState(this);
 190    }
 191
 192    /// <summary>
 193    /// Sets the current status of the activity.
 194    /// </summary>
 195    public void TransitionTo(ActivityStatus status)
 196    {
 7089197        Status = status;
 7089198    }
 199
 200    /// <summary>
 201    /// Gets or sets the exception that occurred during the activity execution, if any.
 202    /// </summary>
 203    public Exception? Exception
 204    {
 3338205        get => _exception;
 206        set
 207        {
 16208            _exception = value;
 16209            Taint();
 16210        }
 211    }
 212
 213    /// <inheritdoc />
 12514214    public IDictionary<string, object> Properties { get; private set; }
 215
 216    /// <summary>
 217    /// A transient dictionary of values that can be associated with this activity execution context.
 218    /// These properties only exist while the activity executes and are not persisted.
 219    /// </summary>
 43500220    public IDictionary<object, object> TransientProperties { get; set; } = new Dictionary<object, object>();
 221
 222    /// <summary>
 223    /// A dictionary of metadata about this execution. In contrast to <see cref="Properties"/>, this metadata is never p
 224    /// </summary>
 7909225    public IDictionary<string, object> Metadata { get; private set; }
 226
 227    /// <summary>
 228    /// Returns the <see cref="ActivityNode"/> metadata about the current activity.
 229    /// </summary>
 31112230    public ActivityNode ActivityNode => WorkflowExecutionContext.FindNodeByActivity(Activity)!;
 231
 232    /// <summary>
 233    /// Returns the global node ID for the current activity within the graph.
 234    /// </summary>
 235    /// <remarks>As of tool version 3.0, all activity IDs are already unique, so there's no need to construct a hierarch
 10807236    public string NodeId => ActivityNode.NodeId;
 237
 14312238    public ISet<ActivityExecutionContext> Children { get; } = new HashSet<ActivityExecutionContext>();
 239
 240    /// <summary>
 241    /// A list of bookmarks associated with the current activity.
 242    /// </summary>
 3493243    public IEnumerable<Bookmark> Bookmarks => WorkflowExecutionContext.Bookmarks.Where(x => x.ActivityInstanceId == Id);
 244
 245    /// <summary>
 246    /// A collection of bookmarks created during the execution of the activity.
 247    /// </summary>
 648248    public IEnumerable<Bookmark> NewBookmarks => _newBookmarks.AsReadOnly();
 249
 250    /// <summary>
 251    /// The number of times this <see cref="ActivityExecutionContext"/> has executed.
 252    /// </summary>
 0253    public long ExecutionCount => _executionCount;
 254
 255    /// <summary>
 256    /// A dictionary of received inputs for the current workflow.
 257    /// </summary>
 294258    public IDictionary<string, object> WorkflowInput => WorkflowExecutionContext.Input;
 259
 260    /// <summary>
 261    /// A dictionary of inputs for the current activity.
 262    /// </summary>
 7621263    public IDictionary<string, object> ActivityInput { get; private set; }
 264
 265    /// <summary>
 266    /// Journal data will be added to the workflow execution log for the "Executed" event.
 267    /// </summary>
 268    // ReSharper disable once CollectionNeverQueried.Global
 7233269    public IDictionary<string, object> JournalData { get; } = new Dictionary<string, object>();
 270
 271    /// <summary>
 272    /// Stores the evaluated inputs, serialized, for the current activity for historical purposes.
 273    /// </summary>
 10299274    public IDictionary<string, object> ActivityState { get; }
 275
 276    /// <summary>
 277    /// Indicates whether the state of the current activity execution context has been modified.
 278    /// </summary>
 30524279    public bool IsDirty { get; private set; }
 280
 281    /// <summary>
 282    /// Schedules the specified activity to be executed.
 283    /// </summary>
 284    /// <param name="activity">The activity to schedule.</param>
 285    /// <param name="completionCallback">An optional callback to invoke when the activity completes.</param>
 286    /// <param name="tag">An optional tag to associate with the activity execution.</param>
 287    /// <param name="variables">An optional list of variables to declare with the activity execution.</param>
 288    public ValueTask ScheduleActivityAsync(IActivity? activity, ActivityCompletionCallback? completionCallback, object? 
 289    {
 2872290        var options = new ScheduleWorkOptions
 2872291        {
 2872292            CompletionCallback = completionCallback,
 2872293            Tag = tag,
 2872294            Variables = variables?.ToList()
 2872295        };
 2872296        return ScheduleActivityAsync(activity, options);
 297    }
 298
 299    /// <summary>
 300    /// Schedules the specified activity to be executed.
 301    /// </summary>
 302    /// <param name="activity">The activity to schedule.</param>
 303    /// <param name="options">The options used to schedule the activity.</param>
 304    public async ValueTask ScheduleActivityAsync(IActivity? activity, ScheduleWorkOptions? options = null)
 305    {
 2895306        await ScheduleActivityAsync(activity, this, options);
 2895307    }
 308
 309    /// <summary>
 310    /// Schedules the specified activity to be executed.
 311    /// </summary>
 312    /// <param name="activity">The activity to schedule.</param>
 313    /// <param name="owner">The activity execution context that owns the scheduled activity.</param>
 314    /// <param name="options">The options used to schedule the activity.</param>
 315    public async ValueTask ScheduleActivityAsync(IActivity? activity, ActivityExecutionContext? owner, ScheduleWorkOptio
 316    {
 2895317        var schedulerStrategy = GetRequiredService<IActivityExecutionContextSchedulerStrategy>();
 2895318        await schedulerStrategy.ScheduleActivityAsync(this, activity, owner, options);
 2895319    }
 320
 321    /// <summary>
 322    /// Schedules the specified activity to be executed.
 323    /// </summary>
 324    /// <param name="activityNode">The activity node to schedule.</param>
 325    /// <param name="owner">The activity execution context that owns the scheduled activity.</param>
 326    /// <param name="options">The options used to schedule the activity.</param>
 327    public async Task ScheduleActivityAsync(ActivityNode? activityNode, ActivityExecutionContext? owner = null, Schedule
 328    {
 0329        var schedulerStrategy = GetRequiredService<IActivityExecutionContextSchedulerStrategy>();
 0330        await schedulerStrategy.ScheduleActivityAsync(this, activityNode, owner, options);
 0331    }
 332
 333    /// <summary>
 334    /// Schedules the specified activities to be executed.
 335    /// </summary>
 336    /// <param name="activities">The activities to schedule.</param>
 0337    public async ValueTask ScheduleActivitiesAsync(params IActivity?[] activities) => await ScheduleActivities(activitie
 338
 339    /// <summary>
 340    /// Schedules the specified activities to be executed.
 341    /// </summary>
 342    /// <param name="activities">The activities to schedule.</param>
 343    /// <param name="completionCallback">The callback to invoke when the activities complete.</param>
 344    /// <param name="tag">An optional tag to associate with the activity execution.</param>
 345    /// <param name="variables">An optional list of variables to declare with the activity execution.</param>
 346    public ValueTask ScheduleActivities(IEnumerable<IActivity?> activities, ActivityCompletionCallback? completionCallba
 347    {
 3348        var options = new ScheduleWorkOptions
 3349        {
 3350            CompletionCallback = completionCallback,
 3351            Tag = tag,
 3352            Variables = variables?.ToList()
 3353        };
 3354        return ScheduleActivities(activities, options);
 355    }
 356
 357    /// <summary>
 358    /// Schedules the specified activities to be executed.
 359    /// </summary>
 360    /// <param name="activities">The activities to schedule.</param>
 361    /// <param name="options">The options used to schedule the activities.</param>
 362    public async ValueTask ScheduleActivities(IEnumerable<IActivity?> activities, ScheduleWorkOptions? options = null)
 363    {
 16364        foreach (var activity in activities)
 5365            await ScheduleActivityAsync(activity, options);
 3366    }
 367
 368    /// <summary>
 369    /// Creates a bookmark for each payload.
 370    /// </summary>
 371    /// <param name="payloads">The payloads to create bookmarks for.</param>
 372    /// <param name="callback">An optional callback that is invoked when the bookmark is resumed.</param>
 373    /// <param name="includeActivityInstanceId">Whether or not the activity instance ID should be included in the bookma
 374    public void CreateBookmarks(IEnumerable<object> payloads, ExecuteActivityDelegate? callback = null, bool includeActi
 375    {
 28376        foreach (var payload in payloads)
 7377            CreateBookmark(new()
 7378            {
 7379                Stimulus = payload,
 7380                Callback = callback,
 7381                IncludeActivityInstanceId = includeActivityInstanceId
 7382            });
 7383    }
 384
 385    /// <summary>
 386    /// Adds each bookmark to the list of bookmarks.
 387    /// </summary>
 388    /// <param name="bookmarks">The bookmarks to add.</param>
 389    public void AddBookmarks(IEnumerable<Bookmark> bookmarks)
 390    {
 0391        WorkflowExecutionContext.Bookmarks.AddRange(bookmarks);
 0392        Taint();
 0393    }
 394
 395    /// <summary>
 396    /// Adds a bookmark to the list of bookmarks.
 397    /// </summary>
 398    /// <param name="bookmark">The bookmark to add.</param>
 399    public void AddBookmark(Bookmark bookmark)
 400    {
 69401        _newBookmarks.Add(bookmark);
 69402        WorkflowExecutionContext.Bookmarks.Add(bookmark);
 69403        Taint();
 69404    }
 405
 406    /// <summary>
 407    /// Creates a bookmark so that this activity can be resumed at a later time.
 408    /// </summary>
 409    /// <param name="callback">An optional callback that is invoked when the bookmark is resumed.</param>
 410    /// <param name="metadata">Custom properties to associate with the bookmark.</param>
 411    /// <returns>The created bookmark.</returns>
 412    public Bookmark CreateBookmark(ExecuteActivityDelegate callback, IDictionary<string, string>? metadata = null)
 413    {
 3414        return CreateBookmark(new()
 3415        {
 3416            Callback = callback,
 3417            Metadata = metadata
 3418        });
 419    }
 420
 421    /// <summary>
 422    /// Creates a bookmark so that this activity can be resumed at a later time.
 423    /// </summary>
 424    /// <param name="stimulus">The payload to associate with the bookmark.</param>
 425    /// <param name="callback">An optional callback that is invoked when the bookmark is resumed.</param>
 426    /// <param name="includeActivityInstanceId">Whether or not the activity instance ID should be included in the bookma
 427    /// <param name="customProperties">Custom properties to associate with the bookmark.</param>
 428    /// <returns>The created bookmark.</returns>
 429    public Bookmark CreateBookmark(object stimulus, ExecuteActivityDelegate? callback, bool includeActivityInstanceId = 
 430    {
 0431        return CreateBookmark(new()
 0432        {
 0433            Stimulus = stimulus,
 0434            Callback = callback,
 0435            IncludeActivityInstanceId = includeActivityInstanceId,
 0436            Metadata = customProperties
 0437        });
 438    }
 439
 440    /// <summary>
 441    /// Creates a bookmark for the current activity execution context.
 442    /// </summary>
 443    /// <param name="stimulus">The payload to associate with the bookmark.</param>
 444    /// <param name="includeActivityInstanceId">Specifies whether to include the activity instance ID in the bookmark in
 445    /// <param name="customProperties">Additional custom properties to associate with the bookmark. Defaults to null.</p
 446    /// <returns>The created bookmark.</returns>
 447    public Bookmark CreateBookmark(object stimulus, bool includeActivityInstanceId, IDictionary<string, string>? customP
 448    {
 0449        return CreateBookmark(new()
 0450        {
 0451            Stimulus = stimulus,
 0452            IncludeActivityInstanceId = includeActivityInstanceId,
 0453            Metadata = customProperties
 0454        });
 455    }
 456
 457    /// <summary>
 458    /// Creates a bookmark so that this activity can be resumed at a later time.
 459    /// </summary>
 460    /// <param name="stimulus">The payload to associate with the bookmark.</param>
 461    /// <param name="metadata">Custom properties to associate with the bookmark.</param>
 462    /// <returns>The created bookmark.</returns>
 463    public Bookmark CreateBookmark(object stimulus, IDictionary<string, string>? metadata = null)
 464    {
 9465        return CreateBookmark(new()
 9466        {
 9467            Stimulus = stimulus,
 9468            Metadata = metadata
 9469        });
 470    }
 471
 472    /// <summary>
 473    /// Creates a bookmark so that this activity can be resumed at a later time.
 474    /// Creating a bookmark will automatically suspend the workflow after all pending activities have executed.
 475    /// </summary>
 476    public Bookmark CreateBookmark(CreateBookmarkArgs? options = null)
 477    {
 69478        var payload = options?.Stimulus;
 69479        var callback = options?.Callback;
 69480        var bookmarkName = options?.BookmarkName ?? Activity.Type;
 69481        var bookmarkHasher = GetRequiredService<IStimulusHasher>();
 69482        var identityGenerator = GetRequiredService<IIdentityGenerator>();
 69483        var includeActivityInstanceId = options?.IncludeActivityInstanceId ?? true;
 69484        var hash = bookmarkHasher.Hash(bookmarkName, payload, includeActivityInstanceId ? Id : null);
 69485        var bookmarkId = options?.BookmarkId ?? identityGenerator.GenerateId();
 486
 69487        var bookmark = new Bookmark(
 69488            bookmarkId,
 69489            bookmarkName,
 69490            hash,
 69491            payload,
 69492            Activity.Id,
 69493            ActivityNode.NodeId,
 69494            Id,
 69495            _systemClock.UtcNow,
 69496            options?.AutoBurn ?? true,
 69497            callback?.Method.Name,
 69498            options?.AutoComplete ?? true,
 69499            options?.Metadata);
 500
 69501        AddBookmark(bookmark);
 69502        return bookmark;
 503    }
 504
 505    /// <summary>
 506    /// Clear all bookmarks.
 507    /// </summary>
 508    public void ClearBookmarks()
 509    {
 3329510        _newBookmarks.Clear();
 3389511        WorkflowExecutionContext.Bookmarks.RemoveWhere(x => x.ActivityInstanceId == Id);
 3329512        Taint();
 3329513    }
 514
 515    /// <summary>
 516    /// Returns a property value associated with the current activity context.
 517    /// </summary>
 1320518    public T? GetProperty<T>(string key) => Properties.TryGetValue<T?>(key, out var value) ? value : default;
 519
 520    /// <summary>
 521    /// Returns a property value associated with the current activity context.
 522    /// </summary>
 523    public T GetProperty<T>(string key, Func<T> defaultValue)
 524    {
 125525        if (Properties.TryGetValue<T?>(key, out var value))
 97526            return value!;
 527
 28528        value = defaultValue();
 28529        Properties[key] = value!;
 530
 28531        return value!;
 532    }
 533
 534    /// <summary>
 535    /// Stores a property associated with the current activity context.
 536    /// </summary>
 100537    public void SetProperty<T>(string key, T? value) => Properties[key] = value!;
 538
 539    /// <summary>
 540    /// Updates a property associated with the current activity context.
 541    /// </summary>
 542    public T UpdateProperty<T>(string key, Func<T?, T> updater) where T : notnull
 543    {
 351544        var value = GetProperty<T?>(key);
 351545        value = updater(value);
 351546        Properties[key] = value;
 351547        return value;
 548    }
 549
 550    /// <summary>
 551    /// Removes a property associated with the current activity context.
 552    /// </summary>
 553    /// <param name="key">The property key.</param>
 0554    public void RemoveProperty(string key) => Properties.Remove(key);
 555
 556    /// <summary>
 557    /// Returns a metadata value associated with the current activity context.
 558    /// </summary>
 0559    public T? GetMetadata<T>(string key) => Metadata.TryGetValue<T?>(key, out var value) ? value : default;
 560
 561    /// <summary>
 562    /// Returns a metadata value associated with the current activity context.
 563    /// </summary>
 564    public T GetMetadata<T>(string key, Func<T> defaultValue)
 565    {
 29566        if (Metadata.TryGetValue<T?>(key, out var value))
 13567            return value!;
 568
 16569        value = defaultValue();
 16570        Metadata[key] = value!;
 571
 16572        return value!;
 573    }
 574
 575    /// <summary>
 576    /// Stores a metadata value associated with the current activity context.
 577    /// </summary>
 4578    public void SetMetadata<T>(string key, T? value) => Metadata[key] = value!;
 579
 580    /// <summary>
 581    /// Updates a metadata value associated with the current activity context.
 582    /// </summary>
 583    public T UpdateMetadata<T>(string key, Func<T?, T> updater) where T : notnull
 584    {
 0585        var value = GetMetadata<T?>(key);
 0586        value = updater(value);
 0587        Metadata[key] = value;
 0588        return value;
 589    }
 590
 591    /// <summary>
 592    /// Removes a metadata value associated with the current activity context.
 593    /// </summary>
 594    /// <param name="key">The metadata key.</param>
 0595    public void RemoveMetadata(string key) => Metadata.Remove(key);
 596
 597    /// <summary>
 598    /// Resolves a required service using the service provider.
 599    /// </summary>
 600    /// <typeparam name="T">The service type.</typeparam>
 601    /// <returns>The resolved service.</returns>
 32867602    public T GetRequiredService<T>() where T : notnull => WorkflowExecutionContext.GetRequiredService<T>();
 603
 604    /// <summary>
 605    /// Resolves a required service using the service provider.
 606    /// </summary>
 607    /// <param name="serviceType">The service type.</param>
 608    /// <returns>The resolved service.</returns>
 2978609    public object GetRequiredService(Type serviceType) => WorkflowExecutionContext.GetRequiredService(serviceType);
 610
 611    /// <summary>
 612    /// Resolves a service using the service provider. If not found, a new instance is created.
 613    /// </summary>
 614    /// <typeparam name="T">The service type.</typeparam>
 615    /// <returns>The resolved service.</returns>
 0616    public T GetOrCreateService<T>() where T : notnull => WorkflowExecutionContext.GetOrCreateService<T>();
 617
 618    /// <summary>
 619    /// Resolves a service using the service provider. If not found, a new instance is created.
 620    /// </summary>
 621    /// <param name="serviceType">The service type.</param>
 622    /// <returns>The resolved service.</returns>
 0623    public object GetOrCreateService(Type serviceType) => WorkflowExecutionContext.GetOrCreateService(serviceType);
 624
 625    /// <summary>
 626    /// Resolves a service using the service provider.
 627    /// </summary>
 628    /// <typeparam name="T">The service type.</typeparam>
 629    /// <returns>The resolved service.</returns>
 566630    public T? GetService<T>() where T : notnull => WorkflowExecutionContext.GetService<T>();
 631
 632    /// <summary>
 633    /// Resolves all services of the specified type using the service provider.
 634    /// </summary>
 635    /// <typeparam name="T">The service type.</typeparam>
 636    /// <returns>The resolved services.</returns>
 266637    public IEnumerable<T> GetServices<T>() where T : notnull => WorkflowExecutionContext.GetServices<T>();
 638
 639    /// <summary>
 640    /// Resolves a service using the service provider.
 641    /// </summary>
 642    /// <param name="serviceType">The service type.</param>
 643    /// <returns>The resolved service.</returns>
 0644    public object? GetService(Type serviceType) => WorkflowExecutionContext.GetService(serviceType);
 645
 646    /// <summary>
 647    /// Gets the value of the specified input.
 648    /// </summary>
 649    /// <param name="input">The input.</param>
 650    /// <typeparam name="T">The type of the input.</typeparam>
 651    /// <returns>The input value.</returns>
 2825652    public T? Get<T>(Input<T>? input) => input == null ? default : Get<T>(input.MemoryBlockReference());
 653
 654    /// <summary>
 655    /// Gets the value of the specified output.
 656    /// </summary>
 657    /// <param name="output">The output.</param>
 658    /// <typeparam name="T">The type of the output.</typeparam>
 659    /// <returns>The output value.</returns>
 0660    public T? Get<T>(Output<T>? output) => output == null ? default : Get<T>(output.MemoryBlockReference());
 661
 662    /// <summary>
 663    /// Gets the value of the specified output.
 664    /// </summary>
 665    /// <param name="output">The output.</param>
 666    /// <returns>The output value.</returns>
 4667    public object? Get(Output? output) => output == null ? null : Get(output.MemoryBlockReference());
 668
 669    /// <summary>
 670    /// Gets the value of the specified memory block.
 671    /// </summary>
 672    /// <param name="blockReference">The memory block reference.</param>
 673    /// <returns>The memory block value.</returns>
 674    /// <exception cref="InvalidOperationException">The memory block does not exist.</exception>
 675    public object? Get(MemoryBlockReference blockReference)
 676    {
 2224677        return !TryGet(blockReference, out var value)
 2224678            ? throw new InvalidOperationException($"The memory block '{blockReference}' does not exist.")
 2224679            : value;
 680    }
 681
 682    /// <summary>
 683    /// Gets the value of the specified memory block.
 684    /// </summary>
 685    /// <param name="blockReference">The memory block reference.</param>
 686    /// <typeparam name="T">The type of the memory block.</typeparam>
 687    /// <returns>The memory block value.</returns>
 688    public T? Get<T>(MemoryBlockReference blockReference)
 689    {
 2094690        var value = Get(blockReference);
 2094691        return value != null ? value.ConvertTo<T>() : default;
 692    }
 693
 694    /// <summary>
 695    /// Tries to get the value of the specified memory block.
 696    /// </summary>
 697    /// <param name="blockReference">The memory block reference.</param>
 698    /// <param name="value">The memory block value.</param>
 699    /// <returns>True if the memory block exists, false otherwise.</returns>
 700    public bool TryGet(MemoryBlockReference blockReference, out object? value)
 701    {
 2398702        var memoryBlock = GetMemoryBlock(blockReference);
 703
 2398704        if (memoryBlock != null)
 705        {
 2398706            value = memoryBlock.Value;
 2398707            return true;
 708        }
 709
 0710        value = null;
 0711        return false;
 712    }
 713
 714    /// <summary>
 715    /// Sets a value at the specified memory block.
 716    /// </summary>
 717    /// <param name="blockReference">The memory block reference.</param>
 718    /// <param name="value">The value to set.</param>
 719    /// <param name="configure">An optional callback that can be used to configure the memory block.</param>
 6720    public void Set(MemoryBlockReference blockReference, object? value, Action<MemoryBlock>? configure = null) => Expres
 721
 722    /// <summary>
 723    /// Sets a value at the specified output.
 724    /// </summary>
 725    /// <param name="output">The output.</param>
 726    /// <param name="value">The value to set.</param>
 727    /// <param name="outputName">The name of the output.</param>
 728    /// <typeparam name="T">The type of the output.</typeparam>
 1694729    public void Set<T>(Output<T>? output, T? value, [CallerArgumentExpression("output")] string? outputName = null) => S
 730
 731    /// <summary>
 732    /// Sets a value at the specified output.
 733    /// </summary>
 734    /// <param name="output">The output.</param>
 735    /// <param name="value">The value to set.</param>
 736    /// <param name="outputName">The name of the output.</param>
 737    public void Set(Output? output, object? value, [CallerArgumentExpression("output")] string? outputName = null)
 738    {
 739        // Store the value in the expression execution memory block.
 1719740        ExpressionExecutionContext.Set(output, value);
 741
 742        // Also store the value in the workflow execution transient activity output register.
 1719743        WorkflowExecutionContext.RecordActivityOutput(this, outputName, value);
 1719744    }
 745
 746    /// <summary>
 747    /// Removes all completion callbacks for the current activity.
 748    /// </summary>
 749    public void ClearCompletionCallbacks()
 750    {
 4778751        var entriesToRemove = WorkflowExecutionContext.CompletionCallbacks.Where(x => x.Owner == this).ToList();
 3332752        WorkflowExecutionContext.RemoveCompletionCallbacks(entriesToRemove);
 3332753    }
 754
 755    public void Taint()
 756    {
 16865757        if (!IsDirty)
 3729758            IsDirty = true;
 16865759    }
 760
 761    public void ClearTaint()
 762    {
 3310763        if (IsDirty)
 3310764            IsDirty = false;
 3310765    }
 766
 767    internal void IncrementExecutionCount()
 768    {
 3212769        _executionCount++;
 3212770    }
 771
 772    private MemoryBlock? GetMemoryBlock(MemoryBlockReference locationBlockReference)
 773    {
 2398774        return ExpressionExecutionContext.TryGetBlock(locationBlockReference, out var memoryBlock) ? memoryBlock : null;
 775    }
 776
 777    void IDisposable.Dispose()
 778    {
 0779    }
 780}

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Contexts/ActivityExecutionContext.ExecutionLogEntry.cs

#LineLine coverage
 1using Elsa.Extensions;
 2using Elsa.Workflows.Models;
 3
 4namespace Elsa.Workflows;
 5
 6public partial class ActivityExecutionContext
 7{
 8    /// <summary>
 9    /// Adds a new <see cref="WorkflowExecutionLogEntry"/> to the execution log of the current <see cref="Workflows.Work
 10    /// </summary>
 11    /// <param name="eventName">The name of the event.</param>
 12    /// <param name="message">The message of the event.</param>
 13    /// <param name="source">The source of the activity. For example, the source file name and line number in case of co
 14    /// <param name="payload">Any contextual data related to this event.</param>
 15    /// <returns>Returns the created <see cref="WorkflowExecutionLogEntry"/>.</returns>
 16    public WorkflowExecutionLogEntry AddExecutionLogEntry(string eventName, string? message = null, string? source = nul
 17    {
 662018        var logEntry = new WorkflowExecutionLogEntry(
 662019            Id,
 662020            ParentActivityExecutionContext?.Id,
 662021            Activity.Id,
 662022            Activity.Type,
 662023            Activity.Version,
 662024            Activity.Name,
 662025            NodeId,
 662026            null,
 662027            _systemClock.UtcNow,
 662028            WorkflowExecutionContext.ExecutionLogSequence++,
 662029            eventName,
 662030            message,
 662031            source ?? Activity.GetSource(),
 662032            payload);
 33
 662034        WorkflowExecutionContext.ExecutionLog.Add(logEntry);
 662035        return logEntry;
 36    }
 37}

Methods/Properties

CanCancelActivity()
CancelActivityAsync()
CancelChildActivitiesAsync()
CompleteActivityAsync()
CompleteActivityWithOutcomesAsync(System.String[])
CompleteCompositeAsync()
.ctor(System.String,Elsa.Workflows.WorkflowExecutionContext,Elsa.Workflows.ActivityExecutionContext,Elsa.Workflows.IActivity,Elsa.Workflows.Models.ActivityDescriptor,System.DateTimeOffset,System.Object,Elsa.Common.ISystemClock,System.Threading.CancellationToken)
get_Id()
get_StartedAt()
get_Tag()
get_CompletedAt()
get_IsCompleted()
get_IsExecuting()
get_AggregateFaultCount()
get_WorkflowExecutionContext()
get_ParentActivityExecutionContext()
set_ParentActivityExecutionContext(Elsa.Workflows.ActivityExecutionContext)
get_ExpressionExecutionContext()
get_Variables()
get_DynamicVariables()
get_Activity()
get_ActivityDescriptor()
get_CancellationToken()
get_Status()
set_Status(Elsa.Workflows.ActivityStatus)
EnterExecution()
TransitionTo(Elsa.Workflows.ActivityStatus)
get_Exception()
set_Exception(System.Exception)
get_Properties()
get_TransientProperties()
get_Metadata()
get_ActivityNode()
get_NodeId()
get_Children()
get_Bookmarks()
get_NewBookmarks()
get_ExecutionCount()
get_WorkflowInput()
get_ActivityInput()
get_JournalData()
get_ActivityState()
get_IsDirty()
ScheduleActivityAsync(Elsa.Workflows.IActivity,Elsa.Workflows.ActivityCompletionCallback,System.Object,System.Collections.Generic.IEnumerable`1<Elsa.Workflows.Memory.Variable>)
ScheduleActivityAsync()
ScheduleActivityAsync()
ScheduleActivityAsync()
ScheduleActivitiesAsync()
ScheduleActivities(System.Collections.Generic.IEnumerable`1<Elsa.Workflows.IActivity>,Elsa.Workflows.ActivityCompletionCallback,System.Object,System.Collections.Generic.IEnumerable`1<Elsa.Workflows.Memory.Variable>)
ScheduleActivities()
CreateBookmarks(System.Collections.Generic.IEnumerable`1<System.Object>,Elsa.Workflows.ExecuteActivityDelegate,System.Boolean)
AddBookmarks(System.Collections.Generic.IEnumerable`1<Elsa.Workflows.Models.Bookmark>)
AddBookmark(Elsa.Workflows.Models.Bookmark)
CreateBookmark(Elsa.Workflows.ExecuteActivityDelegate,System.Collections.Generic.IDictionary`2<System.String,System.String>)
CreateBookmark(System.Object,Elsa.Workflows.ExecuteActivityDelegate,System.Boolean,System.Collections.Generic.IDictionary`2<System.String,System.String>)
CreateBookmark(System.Object,System.Boolean,System.Collections.Generic.IDictionary`2<System.String,System.String>)
CreateBookmark(System.Object,System.Collections.Generic.IDictionary`2<System.String,System.String>)
CreateBookmark(Elsa.Workflows.Models.CreateBookmarkArgs)
ClearBookmarks()
GetProperty(System.String)
GetProperty(System.String,System.Func`1<T>)
SetProperty(System.String,T)
UpdateProperty(System.String,System.Func`2<T,T>)
RemoveProperty(System.String)
GetMetadata(System.String)
GetMetadata(System.String,System.Func`1<T>)
SetMetadata(System.String,T)
UpdateMetadata(System.String,System.Func`2<T,T>)
RemoveMetadata(System.String)
GetRequiredService()
GetRequiredService(System.Type)
GetOrCreateService()
GetOrCreateService(System.Type)
GetService()
GetServices()
GetService(System.Type)
Get(Elsa.Workflows.Models.Input`1<T>)
Get(Elsa.Workflows.Models.Output`1<T>)
Get(Elsa.Workflows.Models.Output)
Get(Elsa.Expressions.Models.MemoryBlockReference)
Get(Elsa.Expressions.Models.MemoryBlockReference)
TryGet(Elsa.Expressions.Models.MemoryBlockReference,System.Object&)
Set(Elsa.Expressions.Models.MemoryBlockReference,System.Object,System.Action`1<Elsa.Expressions.Models.MemoryBlock>)
Set(Elsa.Workflows.Models.Output`1<T>,T,System.String)
Set(Elsa.Workflows.Models.Output,System.Object,System.String)
ClearCompletionCallbacks()
Taint()
ClearTaint()
IncrementExecutionCount()
GetMemoryBlock(Elsa.Expressions.Models.MemoryBlockReference)
System.IDisposable.Dispose()
AddExecutionLogEntry(System.String,System.String,System.String,System.Object)