Open Closed

Azure Durable Functions Isolated (Out of Process) #4951


User avatar
0
marketbus created

Are there any guidelines for integrating ABP with an Azure Durable Function? I am trying to call my Application Services and Repositories.

This is my Program.cs

var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(x => x.UseMiddleware(), options => {})
.ConfigureAppConfiguration((hostContext, config) =>
{
   config.AddJsonFile("appsettings.json", optional: false);
})
.ConfigureServices((hostBuilderContext, services) =>
{
   services.AddOptions();
   services.AddApplicationAsync(x =>
   {
       x.Services.ReplaceConfiguration(hostBuilderContext.Configuration);
   });

    services.Configure<ProcessorOptions>(hostBuilderContext.Configuration.GetSection(nameof(ProcessorOptions)));
    var processorOptions = hostBuilderContext.Configuration.Get<ProcessorOptions>();

    services.AddLogging();
})
.Build();

host.Run();

I am getting a lot of exceptions with trying to access any of my Repositories.


9 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Can you share the error logs?

    And you can check this:

    • https://support.abp.io/QA/Questions/4741/Client-Proxy-from-Azure-Function
    • https://support.abp.io/QA/Questions/4821/Abp-Framework
  • User Avatar
    0
    marketbus created

    I updated the code based upon the links that you've send. I am getting the error as below. I am trying to lookup a user, in the Azure Activity Function I have the following:

    public CreateTestFunction(IIdentityUserRepository identityUserRepository, IProductRepository productRepository)
    {
        _identityUserRepository = identityUserRepository;
        _productRepository = productRepository;
    }
    

    Exception:

    Volo.Abp. AbpInitializationException Create breakpoint: An error occurred during the initialize Volo. Abp. Modularity. OnApplicationInitializationModuleLifecycleContributor phase of the module sVolo.Abp. BackgroundJobs. AbpBackgroundJobsModule, Volo. Abp.BackgroundJobs, Version=7.0.1.0, 2 Culture=neutral, PublicKeyToken=null: Object reference not set to an instance of an object.. See, § the inner exception for details. ---> System. NullReferenceException Create breakpoint : Object reference not set to an instance of an object. at Volo. Abp. BackgroundWorkers. BackgroundWorkerBase. get_Logger at Volo.Abp. BackgroundWorkers. BackgroundWorkerBase. StartAsync(CancellationToken cancellationToken)

    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Volo.Abp;
    using Volo.Abp.Threading;
    using Sample.Processor;
    using Sample.Processor.Options;
    
    var hostBuilder = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults()
        .ConfigureAppConfiguration((hostContext, config) =>
        {
            config.AddJsonFile("appsettings.json", optional: false);
        })
        .ConfigureServices(async (hostBuilderContext, services) =>
        {
            services.AddOptions();
    
            await services.AddApplicationAsync<AzureFunctionProcessorModule>(x =>
            {
                x.Services.ReplaceConfiguration(hostBuilderContext.Configuration);
            });
            
            services.Configure<ProcessorOptions>(hostBuilderContext.Configuration.GetSection(nameof(ProcessorOptions)));
    
            services.AddLogging();
        });
    
    var host = hostBuilder.Build();
    
    var application = host.Services.GetRequiredService<IAbpApplicationWithExternalServiceProvider>();
    var applicationLifetime = host.Services.GetRequiredService<IHostApplicationLifetime>();
    
    applicationLifetime.ApplicationStopping.Register(() =>
    {
        AsyncHelper.RunSync(() => application.ShutdownAsync());
    });
    
    applicationLifetime.ApplicationStopped.Register(() =>
    {
        application.Dispose();
    });
    
    await application.InitializeAsync(host.Services);
    
    host.Run();
    
    
    using Microsoft.Extensions.DependencyInjection;
    using Volo.Abp;
    using Volo.Abp.Autofac;
    using Volo.Abp.Identity;
    using Volo.Abp.Identity.MongoDB;
    using Volo.Abp.Modularity;
    using Sample.MongoDB;
    
    namespace Sample.Processor;
    
    [DependsOn(typeof(WholesaleFriendlyMongoDbModule))]
    [DependsOn(typeof(AbpIdentityApplicationModule))]
    [DependsOn(typeof(AbpAutofacModule))]
    public class AzureFunctionProcessorModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
        }
    
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddTransient<IIdentityUserRepository, MongoIdentityUserRepository>();
        }
        
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
        }
    }
    

    Also, which nugets should I include in this project?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You need to replace dependency injection with autofac

  • User Avatar
    0
    marketbus created

    Do you mind being a bit more specific? Where exactly are you referring to?

    For example, the below produces the same error.

    using Volo.Abp;
    using Volo.Abp.Autofac;
    using Volo.Abp.Identity;
    using Volo.Abp.Modularity;
    using WholesaleFriendly.MongoDB;
    
    namespace WholesaleFriendly.Processor;
    
    [DependsOn(typeof(WholesaleFriendlyMongoDbModule))]
    [DependsOn(typeof(AbpIdentityApplicationModule))]
    [DependsOn(typeof(AbpAutofacModule))]
    public class AzureFunctionProcessorModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
        }
    
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
        }
        
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
        }
    }
    
    
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    I explain how to use Autofac in this answer

    https://support.abp.io/QA/Questions/4821/Abp-Framework#answer-3a0a5c6a-4610-4c66-69ce-549a079f48c8

  • User Avatar
    0
    marketbus created

    The example you gave is for in-process worker functions. But I did update the code as follows, I am still getting an error on some modules, but the below works and I am able to inject IIdentityUserRepository and query it.

    [Program.cs]
    
    using Autofac;
    using Autofac.Extensions.DependencyInjection;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Volo.Abp;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Identity;
    using Volo.Abp.Threading;
    using Sample.SecondProcessor;
    
    var host = new HostBuilder()
        .UseServiceProviderFactory(new AutofacServiceProviderFactory())
        .AddAppSettingsSecretsJson()
        .UseAutofac()
        .ConfigureContainer<ContainerBuilder>(builder =>
        {
        })
        .ConfigureAppConfiguration((hostContext, config) =>
        {
            config.AddJsonFile("appsettings.json", optional: false);
        })
        .ConfigureServices(services =>
        {
            services.AddSingleton<ICancellationTokenProvider>(NullCancellationTokenProvider.Instance);
            services.AddSingleton<IAbpLazyServiceProvider,AbpLazyServiceProvider>();
            
            services.AddApplication<AzureFunctionProcessorModule>(x =>
            {
                x.UseAutofac();
            });        
            
            var serviceProvider = services.BuildServiceProvider();
            
            serviceProvider.GetRequiredService<IAbpApplicationWithExternalServiceProvider>().Initialize(serviceProvider);
        })
        .ConfigureFunctionsWorkerDefaults()
        .Build();
    
    host.Run();
    
    
    [SampleModule.cs]
    
    using Microsoft.Extensions.DependencyInjection;
    using Volo.Abp;
    using Volo.Abp.Autofac;
    using Volo.Abp.BackgroundJobs;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Domain;
    using Volo.Abp.Identity;
    using Volo.Abp.Identity.MongoDB;
    using Volo.Abp.Modularity;
    using Volo.Abp.OpenIddict.Tokens;
    using Volo.Abp.Threading;
    using Volo.Abp.Uow;
    using Sample.MongoDB;
    
    namespace Sample.SecondProcessor;
    
    [DependsOn(
        typeof(AbpIdentityDomainModule),
        typeof(AbpAutofacModule),
        typeof(AbpIdentityMongoDbModule),
        typeof(SampleApplicationContractsModule),
        //typeof(SampleMongoDbModule)
    )]
    
    public class AzureFunctionProcessorModule : AbpModule
    {
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
        }
    
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            context.Services.AddTransient<IIdentityUserRepository, MongoIdentityUserRepository>();
            
            Configure<AbpUnitOfWorkDefaultOptions>(options =>
            {
                options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled;
            });
            
            Configure<AbpBackgroundJobOptions>(options =>
            {
                options.IsJobExecutionEnabled = false;
            });
            
            Configure<TokenCleanupOptions>(options =>
            {
                options.IsCleanupEnabled = false;
            });
        }
        
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
        }
    }
    
    

    If I uncomment SampleMongoDbModule, it fails and I get the generic :

    [2023-05-02T17:58:14.180Z] Language Worker Process exited. Pid=30853. [2023-05-02T17:58:14.180Z] dotnet exited with code 214 (0xD6). . [2023-05-02T17:58:14.277Z] Failed to start a new language worker for runtime: dotnet-isolated. [2023-05-02T17:58:14.277Z] System.Private.CoreLib: A task was canceled.

    Otherwise it works. Also, most of the Pro modules fail with the same error. I thought it might be a license key issue? So I added .AddAppSettingsSecretsJson() and copied my key over. However, it still fails. Also note, that I had to set both IsJobExecutionEnabled and IsCleanupEnabled to false or else it would throw an exception as in the screenshot in my previous comment.

    I believe this will work in In-process mode, but I don't want to have to downgrade my projects to NET 6.0.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    I didn't see the error message about the license, but you should make sure the license code exists in the appsettings.json or appsettings.secret.json file.

    You can check if it is configured correctly this way:

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
         var configuration = context.Services.GetConfiguration();
         
         var licenseCode = configuration["AbpLicenseCode"];
    }
    
  • User Avatar
    0
    marketbus created

    That seemed to be the issue. Even though the appsettings.secret.json file was loaded, which I confirmed, the key was not being loaded. Copying the license key to appsettings.json works. The issue with isolated function apps is that many errors that are not in-code, are swallowed, and the above generic message is displayed. It's an issue that's been reported many times already. https://github.com/Azure/azure-functions-dotnet-worker/issues/532#issuecomment-1384065083

    I might either create a gist or simple guide for this. I lost almost a week trying to get this to work :)

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    ok

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19