temporalio / sdk-dotnet

Temporal .NET SDK

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using dependency injection in a "worker" project hangs

jakejscott opened this issue · comments

What are you really trying to do?

I created a "worker" project template that uses the IHostedService and BackgroundService. I added the ITemporalClient to the services container as a singleton. If I construct the client within the Worker class it works.

https://learn.microsoft.com/en-us/dotnet/core/extensions/workers

Describe the bug

Starting the worker seems to hang

Minimal Reproduction

Program.cs

using Temporalio.Client;

var client = await TemporalClient.ConnectAsync(new TemporalClientConnectOptions
{
    TargetHost = "localhost:7233",
    Namespace = "default",
});

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddLogging(x =>
        {
            x.AddSimpleConsole(options =>
            {
                options.TimestampFormat = "yyyy-mm-ddTHH:mm:ss.ff ";
                options.UseUtcTimestamp = true;
                options.IncludeScopes = false;
                options.SingleLine = true;
            });
        });

        services.AddSingleton<ITemporalClient>(client);

        services.AddHostedService<Worker>();
    })
    .Build();

host.Run();

Worker.cs

using Temporalio.Client;
using Temporalio.Worker;

public class Worker : BackgroundService
{
    private readonly ILoggerFactory _loggerFactory;
    private readonly ILogger<Worker> _logger;
    private readonly ITemporalClient _client;

    public Worker(ILoggerFactory loggerFactory, ILogger<Worker> logger, ITemporalClient client)
    {
        _loggerFactory = loggerFactory;
        _logger = logger;
        _client = client;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Starting worker");
        
        // NOTE: If I connect like this it works. If I use dependency injection it doesn't. 
        // var client = await TemporalClient.ConnectAsync(new TemporalClientConnectOptions
        // {
        //     TargetHost = "localhost:7233",
        //     Namespace = "default",
        // });

        using var worker = new TemporalWorker(_client, new TemporalWorkerOptions
        {
            TaskQueue = "my-task-queue",
            LoggerFactory = _loggerFactory,
            Workflows = new List<Type>
            {
                typeof(SimpleWorkflow)
            }
        });

        await worker.ExecuteAsync(stoppingToken);
        
        _logger.LogInformation("Shutdown worker");
    }
}

x86 Windows
temporal cli

This is surely the same issue as #44. Creating a client on the outside of a DI container is not working (and it's not best practice). See #44 (comment) for the suggested alternative currently. In the meantime I'll try to find out why the external creation is having an issue (even if it is bad practice).

Closing in favor of #44