J'ai une fonction Azure V2. J'ai configuré cette fonction pour n'exécuter qu'une seule fonction en parallèle. Ceci est mon fichier host.json:
{
"version": "2.0",
"extensions": {
"files d'attente": {
"batchSize": 1,
"newBatchThreshold": 0
}
}
}
Lorsque je lance la fonction sur ma machine de développement locale, elle affiche la sortie suivante:
[27-5-2019 12:43:06] Démarrage du service d'initialisation Rpc.
[27-5-2019 12:43:06] Initialisation de RpcServer
[27-5-2019 12:43:06] Hôte du bâtiment: démarrage supprimé: False, configuration supprimé: Faux
[27-5-2019 12:43:07] Initialisation de l'hôte.
[27-5-2019 12:43:07] Initialisation de l'hôte: ConsecutiveErrors = 0, StartupCount = 1
...
[27-5-2019 12:43:07] QueuesOptions
[27-5-2019 12:43:07] {
[27-5-2019 12:43:07] "BatchSize": 16,
[27-5-2019 12:43:07] "NewBatchThreshold": 8,
[27-5-2019 12:43:07] "MaxPollingInterval": "00:00:02",
[27-5-2019 12:43:07] "MaxDequeueCount": 5, **
[27-5-2019 12:43:07] "VisibilityTimeout": "00:00:00"
Suite à cette sortie, il semble ne pas avoir enregistré ces paramètres. Le comportement montre également cela car la fonction s'exécute en parallèle au lieu d'une à la fois. Qu'est-ce que je fais mal?
Toute aide est appréciée.
Référence à la spécification a>
4 Réponses :
On dirait un problème ouvert signalé ici , Fonctions de démarrage ignorées host.json
Si vous avez [assembly: WebJobsStartup (typeof (Startup))]
dans votre code, supprimer cela devrait reconnaître correctement host.json
.
Cela signifie donc que nous n'avons pas de DI ou pas de host.json, ce n'est pas la meilleure situation. Je vais marquer cela comme la réponse pour le moment, car il n'y a pas d'alternative valide
J'ai répondu au même problème (ou similaire) signalé dans github. Pour aider les autres à atterrir ici, je publie à nouveau ici.
Ajout d'un peu plus d'informations pour les autres qui atterrissent ici. De plus, comme je n'ai vu personne d'autre mentionner cela, je peux interpréter / faire mal. Si tel est le cas, veuillez en parler.
Scénario
[assembly: FunctionsStartup (typeof (Startup))]
new ConfigurationBuilder ()
, ajout de mes éléments de configuration IConfigurationRoot
construit comme singleton IConfiguration
Ce que j'ai observé
Définition d'un point d'arrêt avant d'ajouter mon IConfigurationRoot
et de consulter le code IServiceCollection > Je pouvais voir qu'il y avait déjà un singleton
IConfiguration
enregistré. De plus, cette instance contenait le fournisseur host.json, mais il n'était pas chargé lors de l'exécution dans Azure.
Ma théorie
Il semble que lorsque deux singletons du même service sont enregistrés, le framework DI va simplement récupérer le dernier ajouté.
Ma solution
J'ai extrait le IConfiguration du fournisseur IServiceCollection
et l'ajouté au ConfigurationBuilder
afin que ses valeurs soient incluses dans le ConfigurationRoot
que j'enregistre et est donc saisi par le framework DI.
Code
public IConfigurationRoot AddSettings(IServiceCollection services, string basePath, string name, bool optional, bool reloadOnChange) { var builder = new ConfigurationBuilder().SetBasePath(basePath); var existingConfigs = services.Where(svc => svc.ServiceType.Name == "IConfiguration").ToList(); foreach (var cfg in existingConfigs) builder.AddConfiguration((IConfigurationRoot) cfg.ImplementationInstance); // Register/load the requested json settings file builder.AddJsonFile(name, optional, reloadOnChange); // Add all environment vars and build the ConfigurationRoot object. Then register it with the services container builder.AddEnvironmentVariables(); var config = builder.Build(); // Register the resulting IConfigurationRoot to as a singleton services.AddSingleton<IConfiguration>(config); return config; }
J'espère que cela sera utile à quelqu'un
L'idée est là, je pense, mais cela ne fonctionne pas pour moi. Peut-être que je n'appelle pas cette méthode correctement? Je passe le builder.Services
comme premier argument. Ce générateur est un IFunctionsHostBuilder
. Mais alors, cfg.ImplementationInstance
est nul. D'autres astuces?
J'ai fatigué service.Replace
dans la v3 mais cela ne fonctionne pas bien que HostJsonProvider
soit présent dans les sources de configuration
J'avais exactement le même problème que Dave Parker et son analyse d'un nouvel enregistrement de configuration écrasant la configuration host.json était parfaite.
Comme jsgoupil l'a commenté sur le message de Dave, ImplementationInstance
est nul cependant. Voici quelques légères mises à jour du code de Dave pour gérer cela.
public IConfigurationRoot AddSettings(IServiceCollection services, string basePath, string name, bool optional, bool reloadOnChange) { var builder = new ConfigurationBuilder().SetBasePath(basePath); // check if an IConfiguration has already been registered var existingConfig = builder.Services.FirstOrDefault(x => x.ServiceType.Name == nameof(IConfiguration)); if(existingConfig != null) { // get an instance of it and include it in the new config builder var sp = builder.Services.BuildServiceProvider(); var existingInstance = sp.GetService<IConfiguration>(); builder.AddConfiguration(existingInstance); } // Register/load the requested json settings file builder.AddJsonFile(name, optional, reloadOnChange); // Add all environment vars and build the ConfigurationRoot object. Then register it with the services container builder.AddEnvironmentVariables(); var config = builder.Build(); // Register the resulting IConfigurationRoot to as a singleton services.AddSingleton<IConfiguration>(config); return config; }
J'ai eu le même problème. La configuration a été perdue car j'ai créé un nouveau ConfigurationBuilder vide, ajouté som json config et l'ai enregistré. L'ajout de la configuration déjà enregistrée par le runtime a fait l'affaire! Merci Nick!
Cela a aidé mon problème. Merci Nick. Je pense que cela devrait être géré par défaut.
Merci beaucoup pour cela! J'ai utilisé une petite variation car j'utilise l'invocation différée du modèle d'usine pour référencer la configuration au démarrage:
public static IServiceCollection AddConfigurationFactory(this IServiceCollection services) { var configurationEnvironment = Environment.GetEnvironmentVariable("ConfigEnv"); var jsonConfigFilename = $"appsettings.{configurationEnvironment}.json"; #if DEBUG var basePath = Environment.CurrentDirectory; #else var basePath = @"/home/site/wwwroot"; #endif var existingConfig = services.FirstOrDefault(x => x.ServiceType.Name == nameof(IConfiguration)); IConfiguration existingInstance = null; if (existingConfig != null) { var spOuter = services.BuildServiceProvider(); existingInstance = spOuter.GetService<IConfiguration>(); } Func<IServiceProvider, IConfiguration> factory = (sp) => { var configBuilder = new ConfigurationBuilder() .SetBasePath(basePath) .AddEnvironmentVariables() .AddJsonFile(jsonConfigFilename, optional: false, reloadOnChange: true); if (existingInstance != null) configBuilder.AddConfiguration(existingInstance); return configBuilder.Build(); }; services.AddSingleton<IConfiguration>(factory); return services; }
Utilisez-vous le plan Azure App Service ou le plan de consommation?
Plan de consommation, mais cet exemple vient de le frotter en développement.