< 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    {
 249414        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    {
 313215        var outcomes = result as Outcomes;
 16
 17        // If the activity is executing in the background, simply capture the result and return.
 313218        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.
 313228        if (Status != ActivityStatus.Running)
 729            return;
 30
 31        // Cancel any non-completed child activities.
 561932        var childContexts = Children.Where(x => x.CanCancelActivity()).ToList();
 33
 625034        foreach (var childContext in childContexts)
 035            await childContext.CancelActivityAsync();
 36
 37        // Mark the activity as complete.
 312538        TransitionTo(ActivityStatus.Completed);
 39
 40        // Record the outcomes, if any.
 312541        if (outcomes != null)
 10342            JournalData["Outcomes"] = outcomes.Names;
 43
 44        // Add an execution log entry.
 312545        AddExecutionLogEntry("Completed");
 46
 47        // Send a signal.
 312548        await this.SendSignalAsync(new ActivityCompleted(result));
 49
 50        // Clear bookmarks.
 312551        ClearBookmarks();
 315552        WorkflowExecutionContext.Bookmarks.RemoveWhere(x => x.ActivityInstanceId == Id);
 53
 54        // Remove completion callbacks.
 312555        ClearCompletionCallbacks();
 56
 57        // Remove all associated variables, unless this is the root context - in which case we want to keep the variable
 312558        if (ParentActivityExecutionContext != null)
 59        {
 254160            var variablePersistenceManager = GetRequiredService<IVariablePersistenceManager>();
 254161            await variablePersistenceManager.DeleteVariablesAsync(this);
 62        }
 63
 64        // Update the completed at timestamp.
 312565        CompletedAt = WorkflowExecutionContext.SystemClock.UtcNow;
 313266    }
 67
 68    /// <summary>
 69    /// Complete the current activity with the specified outcomes.
 70    /// </summary>
 71    public ValueTask CompleteActivityWithOutcomesAsync(params string[] outcomes)
 72    {
 9873        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.
 354427    private List<Bookmark> _newBookmarks = [];
 28
 29    /// <summary>
 30    /// Initializes a new instance of the <see cref="ActivityExecutionContext"/> class.
 31    /// </summary>
 354432    public ActivityExecutionContext(
 354433        string id,
 354434        WorkflowExecutionContext workflowExecutionContext,
 354435        ActivityExecutionContext? parentActivityExecutionContext,
 354436        IActivity activity,
 354437        ActivityDescriptor activityDescriptor,
 354438        DateTimeOffset startedAt,
 354439        object? tag,
 354440        ISystemClock systemClock,
 354441        CancellationToken cancellationToken)
 42    {
 354443        _systemClock = systemClock;
 354444        Properties = new ChangeTrackingDictionary<string, object>(Taint);
 354445        Metadata = new ChangeTrackingDictionary<string, object>(Taint);
 354446        ActivityState = new ChangeTrackingDictionary<string, object>(Taint);
 354447        ActivityInput = new ChangeTrackingDictionary<string, object>(Taint);
 354448        WorkflowExecutionContext = workflowExecutionContext;
 354449        ParentActivityExecutionContext = parentActivityExecutionContext;
 354450        var expressionExecutionContextProps = ExpressionExecutionContextExtensions.CreateActivityExecutionContextPropert
 354451        expressionExecutionContextProps[ExpressionExecutionContextExtensions.ActivityKey] = activity;
 354452        ExpressionExecutionContext = new(workflowExecutionContext.ServiceProvider, new(), parentActivityExecutionContext
 354453        Activity = activity;
 354454        ActivityDescriptor = activityDescriptor;
 354455        StartedAt = startedAt;
 354456        Status = ActivityStatus.Pending;
 354457        Tag = tag;
 354458        CancellationToken = cancellationToken;
 354459        Id = id;
 354460        _publisher = GetRequiredService<INotificationSender>();
 354461    }
 62
 63    /// <summary>
 64    /// The ID of the current activity execution context.
 65    /// </summary>
 2856166    public string Id { get; set; }
 67
 68    /// <summary>
 69    /// The time at which the activity execution context was created.
 70    /// </summary>
 738171    public DateTimeOffset StartedAt { get; set; }
 72
 73    /// <summary>
 74    /// An optional tag to associate with the activity execution.
 75    /// </summary>
 681676    public object? Tag { get; set; }
 77
 78    /// <summary>
 79    /// The time at which the activity execution context was completed.
 80    /// </summary>
 696281    public DateTimeOffset? CompletedAt { get; set; }
 82
 83    /// <summary>
 84    /// Returns true if the activity execution context has completed.
 85    /// </summary>
 1228486    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>
 674597    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>
 3924102    public int AggregateFaultCount { get; set; }
 103
 104    /// <summary>
 105    /// The workflow execution context.
 106    /// </summary>
 152680107    public WorkflowExecutionContext WorkflowExecutionContext { get; }
 108
 109    /// <summary>
 110    /// The parent activity execution context, if any.
 111    /// </summary>
 112    public ActivityExecutionContext? ParentActivityExecutionContext
 113    {
 57542114        get => _parentActivityExecutionContext;
 115        internal set
 116        {
 3636117            _parentActivityExecutionContext = value;
 3636118            _parentActivityExecutionContext?.Children.Add(this);
 2675119        }
 120    }
 121
 122    /// <summary>
 123    /// The expression execution context.
 124    /// </summary>
 39902125    public ExpressionExecutionContext ExpressionExecutionContext { get; }
 126
 127    /// <inheritdoc />
 128    public IEnumerable<Variable> Variables
 129    {
 130        get
 131        {
 5847132            var containerVariables = (Activity as IVariableContainer)?.Variables ?? Enumerable.Empty<Variable>();
 5847133            var dynamicVariables = DynamicVariables;
 5847134            var mergedVariables = new Dictionary<string, Variable>();
 135
 11840136            foreach (var containerVariable in containerVariables)
 137            {
 73138                var name = !string.IsNullOrEmpty(containerVariable.Name) ? containerVariable.Name : containerVariable.Id
 73139                mergedVariables[name] = containerVariable;
 140            }
 141
 12064142            foreach (var dynamicVariable in dynamicVariables)
 143            {
 185144                var name = !string.IsNullOrEmpty(dynamicVariable.Name) ? dynamicVariable.Name : dynamicVariable.Id;
 185145                mergedVariables[name] = dynamicVariable;
 146            }
 5847147            return mergedVariables.Values;
 148        }
 149    }
 150
 151    /// <summary>
 152    /// A list of variables that are dynamically added to the activity execution context.
 153    /// </summary>
 10272154    public ICollection<Variable> DynamicVariables { get; set; } = new List<Variable>();
 155
 156    /// <summary>
 157    /// The currently executing activity.
 158    /// </summary>
 185182159    public IActivity Activity { get; set; }
 160
 161    /// <summary>
 162    /// The activity descriptor.
 163    /// </summary>
 23651164    public ActivityDescriptor ActivityDescriptor { get; }
 165
 166    /// <summary>
 167    /// A cancellation token to use when invoking asynchronous operations.
 168    /// </summary>
 31867169    public CancellationToken CancellationToken { get; }
 170
 171    /// <summary>
 172    /// The current status of the activity.
 173    /// </summary>
 174    public ActivityStatus Status
 175    {
 36811176        get => _status;
 177        private set
 178        {
 10220179            if (value == _status)
 3580180                return;
 181
 6640182            _status = value;
 6640183            Taint();
 6640184        }
 185    }
 186
 187    public IDisposable EnterExecution()
 188    {
 3019189        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    {
 6676197        Status = status;
 6676198    }
 199
 200    /// <summary>
 201    /// Gets or sets the exception that occurred during the activity execution, if any.
 202    /// </summary>
 203    public Exception? Exception
 204    {
 3131205        get => _exception;
 206        set
 207        {
 15208            _exception = value;
 15209            Taint();
 15210        }
 211    }
 212
 213    /// <inheritdoc />
 11463214    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>
 41118220    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>
 7441225    public IDictionary<string, object> Metadata { get; private set; }
 226
 227    /// <summary>
 228    /// Returns the <see cref="ActivityNode"/> metadata about the current activity.
 229    /// </summary>
 29559230    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
 10133236    public string NodeId => ActivityNode.NodeId;
 237
 13584238    public ISet<ActivityExecutionContext> Children { get; } = new HashSet<ActivityExecutionContext>();
 239
 240    /// <summary>
 241    /// A list of bookmarks associated with the current activity.
 242    /// </summary>
 3286243    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>
 644248    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>
 243258    public IDictionary<string, object> WorkflowInput => WorkflowExecutionContext.Input;
 259
 260    /// <summary>
 261    /// A dictionary of inputs for the current activity.
 262    /// </summary>
 7205263    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
 6817269    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>
 9103274    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>
 28335279    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    {
 2716290        var options = new ScheduleWorkOptions
 2716291        {
 2716292            CompletionCallback = completionCallback,
 2716293            Tag = tag,
 2716294            Variables = variables?.ToList()
 2716295        };
 2716296        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    {
 2739306        await ScheduleActivityAsync(activity, this, options);
 2739307    }
 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    {
 2739317        var schedulerStrategy = GetRequiredService<IActivityExecutionContextSchedulerStrategy>();
 2739318        await schedulerStrategy.ScheduleActivityAsync(this, activity, owner, options);
 2739319    }
 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    {
 24376        foreach (var payload in payloads)
 6377            CreateBookmark(new()
 6378            {
 6379                Stimulus = payload,
 6380                Callback = callback,
 6381                IncludeActivityInstanceId = includeActivityInstanceId
 6382            });
 6383    }
 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    {
 68401        _newBookmarks.Add(bookmark);
 68402        WorkflowExecutionContext.Bookmarks.Add(bookmark);
 68403        Taint();
 68404    }
 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    {
 68478        var payload = options?.Stimulus;
 68479        var callback = options?.Callback;
 68480        var bookmarkName = options?.BookmarkName ?? Activity.Type;
 68481        var bookmarkHasher = GetRequiredService<IStimulusHasher>();
 68482        var identityGenerator = GetRequiredService<IIdentityGenerator>();
 68483        var includeActivityInstanceId = options?.IncludeActivityInstanceId ?? true;
 68484        var hash = bookmarkHasher.Hash(bookmarkName, payload, includeActivityInstanceId ? Id : null);
 68485        var bookmarkId = options?.BookmarkId ?? identityGenerator.GenerateId();
 486
 68487        var bookmark = new Bookmark(
 68488            bookmarkId,
 68489            bookmarkName,
 68490            hash,
 68491            payload,
 68492            Activity.Id,
 68493            ActivityNode.NodeId,
 68494            Id,
 68495            _systemClock.UtcNow,
 68496            options?.AutoBurn ?? true,
 68497            callback?.Method.Name,
 68498            options?.AutoComplete ?? true,
 68499            options?.Metadata);
 500
 68501        AddBookmark(bookmark);
 68502        return bookmark;
 503    }
 504
 505    /// <summary>
 506    /// Clear all bookmarks.
 507    /// </summary>
 508    public void ClearBookmarks()
 509    {
 3125510        _newBookmarks.Clear();
 3185511        WorkflowExecutionContext.Bookmarks.RemoveWhere(x => x.ActivityInstanceId == Id);
 3125512        Taint();
 3125513    }
 514
 515    /// <summary>
 516    /// Returns a property value associated with the current activity context.
 517    /// </summary>
 970518    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    {
 250544        var value = GetProperty<T?>(key);
 250545        value = updater(value);
 250546        Properties[key] = value;
 250547        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>
 29764602    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>
 2564609    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>
 214637    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>
 2485652    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    {
 1914677        return !TryGet(blockReference, out var value)
 1914678            ? throw new InvalidOperationException($"The memory block '{blockReference}' does not exist.")
 1914679            : 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    {
 1834690        var value = Get(blockReference);
 1834691        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    {
 2034702        var memoryBlock = GetMemoryBlock(blockReference);
 703
 2034704        if (memoryBlock != null)
 705        {
 2034706            value = memoryBlock.Value;
 2034707            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>
 1426729    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.
 1451740        ExpressionExecutionContext.Set(output, value);
 741
 742        // Also store the value in the workflow execution transient activity output register.
 1451743        WorkflowExecutionContext.RecordActivityOutput(this, outputName, value);
 1451744    }
 745
 746    /// <summary>
 747    /// Removes all completion callbacks for the current activity.
 748    /// </summary>
 749    public void ClearCompletionCallbacks()
 750    {
 4466751        var entriesToRemove = WorkflowExecutionContext.CompletionCallbacks.Where(x => x.Owner == this).ToList();
 3128752        WorkflowExecutionContext.RemoveCompletionCallbacks(entriesToRemove);
 3128753    }
 754
 755    public void Taint()
 756    {
 15505757        if (!IsDirty)
 3521758            IsDirty = true;
 15505759    }
 760
 761    public void ClearTaint()
 762    {
 3103763        if (IsDirty)
 3103764            IsDirty = false;
 3103765    }
 766
 767    internal void IncrementExecutionCount()
 768    {
 3006769        _executionCount++;
 3006770    }
 771
 772    private MemoryBlock? GetMemoryBlock(MemoryBlockReference locationBlockReference)
 773    {
 2034774        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    {
 620818        var logEntry = new WorkflowExecutionLogEntry(
 620819            Id,
 620820            ParentActivityExecutionContext?.Id,
 620821            Activity.Id,
 620822            Activity.Type,
 620823            Activity.Version,
 620824            Activity.Name,
 620825            NodeId,
 620826            null,
 620827            _systemClock.UtcNow,
 620828            WorkflowExecutionContext.ExecutionLogSequence++,
 620829            eventName,
 620830            message,
 620831            source ?? Activity.GetSource(),
 620832            payload);
 33
 620834        WorkflowExecutionContext.ExecutionLog.Add(logEntry);
 620835        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)