elsa-workflows / elsa-core

A .NET workflows library
https://v3.elsaworkflows.io/
MIT License
6.33k stars 1.17k forks source link

Onresume not fires and Workflow remains suspended #4002

Open osmankoc opened 1 year ago

osmankoc commented 1 year ago

Hi,

I created a solution based on the tutorial on https://medium.com/codex/part-6-of-building-workflow-driven-net-applications-with-elsa-2-9b3167c612dd .

At the Updateblockchain step workflow remains suspended.

Source code is DocumentManagement.zip

Thanks..

`

namespace DocumentManagement.Workflows.Activities { [Activity( Category = "Document Management", Description = "Saves a hash of the specified file onto the blockchain to prevent tampering." )] public class UpdateBlockchain : Activity { public record UpdateBlockchainContext(string WorkflowInstanceId, string ActivityId, string FileSignature);

    private readonly IBackgroundJobClient _backgroundJobClient;
    private readonly IWorkflowInstanceDispatcher _workflowInstanceDispatcher;

    public UpdateBlockchain(IBackgroundJobClient backgroundJobClient, IWorkflowInstanceDispatcher workflowInstanceDispatcher)
    {
        _backgroundJobClient = backgroundJobClient;
        _workflowInstanceDispatcher = workflowInstanceDispatcher;
    }

    [ActivityInput(
        Label = "File",
        Hint = "The file to store its hash of onto the blockchain. Can be byte[] or Stream.",
        SupportedSyntaxes = new[] { SyntaxNames.JavaScript, SyntaxNames.Liquid },
        DefaultWorkflowStorageProvider = TransientWorkflowStorageProvider.ProviderName
    )]
    public object File { get; set; } = default!;

    [ActivityOutput(Hint = "The computed file signature as stored on the blockchain.")]
    public string Output { get; set; } = default!;

    /// <summary>
    /// Invoked by Hangfire as a background job.
    /// </summary>
    public async Task SubmitToBlockChainAsync(UpdateBlockchainContext context, CancellationToken cancellationToken)
    {
        // Simulate storing it on an imaginary blockchain out there.
        await Task.Delay(TimeSpan.FromSeconds(15), cancellationToken);

        // Resume the suspended workflow.
        await _workflowInstanceDispatcher.DispatchAsync(new ExecuteWorkflowInstanceRequest(context.WorkflowInstanceId, context.ActivityId, new WorkflowInput(context.FileSignature)), cancellationToken);
    }

    protected override async ValueTask<IActivityExecutionResult> OnExecuteAsync(ActivityExecutionContext context)
    {
        // Compute hash.
        var bytes = File is Stream stream ? await stream.ReadBytesToEndAsync() : File is byte[] buffer ? buffer : throw new NotSupportedException();
        var fileSignature = ComputeSignature(bytes);

        // Schedule background work using Hangfire.
        _backgroundJobClient.Enqueue(() => SubmitToBlockChainAsync(new UpdateBlockchainContext(context.WorkflowInstance.Id, context.ActivityId, fileSignature), CancellationToken.None));

        // Suspend the workflow.
        return Suspend();
    }

    protected override IActivityExecutionResult OnResume(ActivityExecutionContext context)
    {
        // When we resume, simply complete this activity.
        var fileSignature = context.GetInput<string>();
        Output = fileSignature;
        return Done();
    }

    private static string ComputeSignature(byte[] bytes)
    {
        using var algorithm = SHA256.Create();
        var hashValue = algorithm.ComputeHash(bytes);
        return Convert.ToBase64String(hashValue);
    }
}

}`

osmankoc commented 1 year ago

Any help? activity never resumes and instance remains suspended :(

sfmskywalker commented 1 year ago

I'll take a look as soon as I can, this issue is on my shortlist for this week.

osmankoc commented 1 year ago

Hi. Any progress on this?

sfmskywalker commented 1 year ago

Hi! I downloaded your zip file and ran the solution, and I was able to run the workflow without it remaining suspended. In other words, the workflow ran from start to end.

Keep in mind, though, that the IndexBlockchain activity emulates a long-running job by waiting for 15 seconds, before resuming execution.

osmankoc commented 1 year ago

But i Didn't get the same result. What am i doing wrong?

sfmskywalker commented 1 year ago

I don't know, but I can show you what I did:

https://github.com/elsa-workflows/elsa-core/assets/938393/d26681c3-e809-4581-bf08-0245f43ccf16

osmankoc commented 1 year ago

Unfortunately i can't see the video :(

sfmskywalker commented 1 year ago

Have you tried downloading it?

osmankoc commented 1 year ago

Ok. I saw. Bu it simply not works on my development machine. I also tried it on my coworkers' dev machine either. We use vs 2022. .net core 6.0.

You didn't make any library or package changes on the solution right?

sfmskywalker commented 1 year ago

No changes were made - I literally took your zip file and run it on port 11000 and connected the designer to it. No package references were updated.

osmankoc commented 1 year ago

So any suggestions?

sfmskywalker commented 1 year ago

Yes, try and debug what’s going on. The easiest way to do so is to clone the Elsa source code and reference the projects directly instead of the packages, this way you can step through the source code.

Unfortunately there’s little I can do if I can’t reproduce the problem.

osmankoc commented 1 year ago

Thanks. I'll try that and if i find the problem i'll give you update from here.

sfmskywalker commented 1 year ago

Sounds good, thanks!

osmankoc commented 1 year ago

Hello there.

I took a break for workflows for some time. Today i gave another try on this issue, and finally found the problem. The issue is probably lowercase to create job que name is working according to local culture.

execute-workflow-ınstance-request-default

{"WorkerCount":1,"Queues":["default","trigger-workflows-request","execute-workflow-definition-request-default","execute-workflow-ınstance-request-default"],"StartedAt":"2023-07-28T14:25:49.0071871Z"}

after i addd this line at the top of the Program.cs it worked well.

Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;