Giter Site home page Giter Site logo

Comments (11)

KenHundley avatar KenHundley commented on August 17, 2024 2

Hey @jsauter, that's intended behavior.

You can see the details for IOptions and IOptionsSnapshot at Options pattern in ASP.NET Core

Specifically the lines:

IOptions:

  • Does not support:
    • Reading of configuration data after the app has started.
      This is because it's a singleton that's only populated once

IOptionsSnapshot:

  • Use IOptionsSnapshot to read updated data.

from aws-dotnet-extensions-configuration.

ashishdhingra avatar ashishdhingra commented on August 17, 2024 1

Another possible related issue #17.

@jsauter Feel free to submit a PR which could be reviewed by development team.

from aws-dotnet-extensions-configuration.

KenHundley avatar KenHundley commented on August 17, 2024 1

@KenHundley I have not tested this level yet, do the IOptionsSnapshot trigger a SSM query on each request, or are they updating from the SystemsManager which is scheduled to reload via the reloadAfter parameter?

It's kind of both from my understanding. There is a "pool" of data from all the configs that's maintained. The SSM reload only updates on the supplied schedule and updates that "pool" of data with the new values. The IOptions will only read that pool at startup and creates a singleton. The IOptionsSnapshot will read that pool everytime the IOC asks for a new instance.

So basically the SSM reader will run on the schedule (reloadAfter) and update the data pool, but the IOptionsSnapshot will be created and read the current data from the pool on every request

from aws-dotnet-extensions-configuration.

Kralizek avatar Kralizek commented on August 17, 2024 1

@ashishdhingra great finding about the scope in the console application!

from aws-dotnet-extensions-configuration.

jsauter avatar jsauter commented on August 17, 2024

@KenHundley I have not tested this level yet, do the IOptionsSnapshot trigger a SSM query on each request, or are they updating from the SystemsManager which is scheduled to reload via the reloadAfter parameter?

from aws-dotnet-extensions-configuration.

artempaskhin avatar artempaskhin commented on August 17, 2024

Good package BUT,
at

  ChangeToken.OnChange(() =>
                {
                    var cancellationTokenSource = new CancellationTokenSource(source.ReloadAfter.Value);
                    var cancellationChangeToken = new CancellationChangeToken(cancellationTokenSource.Token);
                    return cancellationChangeToken;
                }, async () =>

There is a bug here.
"cancellationChangeToken" will be recycled by GC
I suggest for Author to borrow timed reloading logics from here
https://github.com/Wallsmedia/DotNetCore.Azure.Configuration.KvSecrets/blob/master/src/AzureKvConfigurationProvider.cs
it should send also notifications "OnReload();" as well.

from aws-dotnet-extensions-configuration.

Kralizek avatar Kralizek commented on August 17, 2024

I have the same issue and I'm using IOptionsSnapshot<T>.

Here is my short repro (written using .NET 6.0). Also available as repository: https://github.com/Kralizek/ParameterStoreReloadRepro

Source:

using Amazon;
using Amazon.Extensions.NETCore.Setup;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

var aws = new AWSOptions {Region = RegionEndpoint.EUWest1 };

var builder = new ConfigurationBuilder();
builder.AddSystemsManager("/ParameterStoreReload/TestApp", aws, TimeSpan.FromSeconds(1));

var configuration = builder.Build();

var services = new ServiceCollection();

services.AddOptions();

services.AddTransient<Service>();
services.Configure<ServiceOptions>(configuration);

var sp = services.BuildServiceProvider();

while (true)
{
    var svc = sp.GetRequiredService<Service>();

    svc.PrintValue();

    await Task.Delay(TimeSpan.FromMilliseconds(500));
}

public class Service
{
    private readonly IOptionsSnapshot<ServiceOptions> _options;

    public Service(IOptionsSnapshot<ServiceOptions> options)
    {
        _options = options ?? throw new ArgumentNullException(nameof(options));
    }

    public void PrintValue()
    {
        Console.WriteLine($"{Guid.NewGuid():D}: {_options.Value.Value}");
    }
}

public class ServiceOptions
{
    public int Value { get; set; }
}

Project file

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
    <PackageReference Include="Amazon.Extensions.Configuration.SystemsManager" Version="3.0.0" />
    <PackageReference Include="AWSSDK.Extensions.NetCore.Setup" Version="3.7.1" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="6.0.0" />
  </ItemGroup>

</Project>

Output:

8b45e161-4de5-40fe-8a01-d9f637c0b94c: 42
3adfe477-8831-4bd3-9afb-79100f8d8a0f: 42
37300fcd-e002-44de-a1e3-4432dd5ddd2f: 42
a9a3869b-45e6-42fd-8e8b-382135c0e227: 42
<< change value in console >>
5d15720a-c6b6-4a22-857e-cc3dcb5b26b0: 42
ced37d62-ea12-40ea-aa3c-b90a72168f70: 42
a6daf888-3917-4afa-8eb2-0ddefe392665: 42
95d903e3-8b52-4744-8fb1-2a1ab632fc43: 42

from aws-dotnet-extensions-configuration.

Kralizek avatar Kralizek commented on August 17, 2024

@ashishdhingra when you have time, can you confirm the comment above is able to reproduce the issue?

from aws-dotnet-extensions-configuration.

ashishdhingra avatar ashishdhingra commented on August 17, 2024

@ashishdhingra when you have time, can you confirm the comment above is able to reproduce the issue?

@Kralizek I tested using the code above. The ConfigReload happened when examined via Fiddler:

  • Initial value was 52.
    Screenshot 2023-05-03 at 11 35 24 AM

  • Then changed the value to 100 in Systems Manager parameter store in AWS console. Fiddler displayed the call with updated response from SSM.
    Screenshot 2023-05-03 at 11 35 52 AM

The library code is reloading the value, but somehow, it is not reflected in IOptionsSnapshot in above code. Need to investigate more from .NET perspective, doesn't appear to be a bug with this library (need to check if there is some cached value not being updated, also revisit #97 (comment)).

Reproduction Steps:

  • Created System Manager parameter /myapplication/Value with some value.
  • Code below:
    Program.cs
//using Amazon;
using Amazon;
using Amazon.Extensions.NETCore.Setup;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

var aws = new AWSOptions { Region = RegionEndpoint.USEast2 };

var builder = new ConfigurationBuilder();
builder.AddSystemsManager("/myapplication", aws, TimeSpan.FromSeconds(1));

var configuration = builder.Build();

var services = new ServiceCollection();

services.AddOptions();

services.AddTransient<Service>();
services.Configure<ServiceOptions>(configuration);

var sp = services.BuildServiceProvider();

while (true)
{
var svc = sp.GetRequiredService<Service>();

svc.PrintValue();

await Task.Delay(TimeSpan.FromMilliseconds(500));
}

public class Service
{
    private readonly IOptionsSnapshot<ServiceOptions> _options;

    public Service(IOptionsSnapshot<ServiceOptions> options)
    {
        _options = options ?? throw new ArgumentNullException(nameof(options));
    }

    public void PrintValue()
    {
        Console.WriteLine($"{Guid.NewGuid():D}: {_options.Value.Value}");
    }
}

public class ServiceOptions
{
    public int Value { get; set; }
}

.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Amazon.Extensions.Configuration.SystemsManager" Version="5.0.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Options" Version="7.0.1" />
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
  </ItemGroup>

</Project>
  • Opened Fiddler to monitor network traffic.
  • Changed the value in system manager parameter store.
  • Monitored Fiddler for network traffic.

EDIT 1: Based on debugging, the new values from System Manager parameter store are being loaded. The SystemsManagerConfigurationProvider is getting the updated value when examined via debug watch window. However, IOptionsSnapshot is somehow not loading the updated value.

EDIT 2: Unsure why IOptionsSnapshot is not working with Console application, it works in ASP.NET application.
Reproduction Steps:

  • Created parameter /myapplication/Value of Type String and value 210
  • Created ASP.NET Core Web application targeting .NET 6.0.
    • Added reference to NuGet package Amazon.Extensions.Configuration.SystemsManager version 5.0.2.
    • Added class ServiceOptions in Program.cs:
public class ServiceOptions
{
    public int Value { get; set; }
}
  • Modified Program.cs to add below line before var app = builder.Build() (here we have configured reload to happen after 10 seconds):
builder.Configuration.AddSystemsManager("/myapplication", TimeSpan.FromSeconds(10));
builder.Services.Configure<ServiceOptions>(builder.Configuration);
  • Modified Pages\Index.cshtml.cs as below:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Options;

namespace TestParameterStoreAspNet.Pages
{
    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
        private readonly ServiceOptions _snapshotOptions;

        public IndexModel(ILogger<IndexModel> logger, IOptionsSnapshot<ServiceOptions> snapshotOptionsAccessor)
        {
            _logger = logger;
            _snapshotOptions = snapshotOptionsAccessor.Value;
        }

        public ContentResult OnGet()
        {
            return Content($"Service options value: {_snapshotOptions.Value}");
        }
    }
}
  • Ensure that the default credentials profile is setup.
  • Ran the application.

Modifying the value in System Manager parameter store and reloading the web page after 10 seconds (or so) displays the updated value.

EDIT 3: For Console application, service instance should be retrieved in a scope as shown below:

using Amazon;
using Amazon.Extensions.NETCore.Setup;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

var aws = new AWSOptions { Region = RegionEndpoint.USEast2 };

var builder = new ConfigurationBuilder();
builder.AddSystemsManager("/myapplication", aws, TimeSpan.FromSeconds(10));

var configuration = builder.Build();

var services = new ServiceCollection();

services.AddOptions();

services.Configure<ServiceOptions>(configuration);
services.AddTransient<Service>();

var sp = services.BuildServiceProvider();

while (true)
{
    using (var serviceScope = sp.CreateScope())
    {
        var service = serviceScope.ServiceProvider.GetRequiredService<Service>();
        service.PrintValue();
    }

    await Task.Delay(TimeSpan.FromMilliseconds(500));
}

public class Service
{
    private readonly IOptionsSnapshot<ServiceOptions> _options;

    public Service(IOptionsSnapshot<ServiceOptions> options)
    {
        _options = options ?? throw new ArgumentNullException(nameof(options));
    }

    public void PrintValue()
    {
        Console.WriteLine($"{Guid.NewGuid():D}: {_options.Value.Value}");
    }
}

public class ServiceOptions
{
    public int Value { get; set; }
}

After using scope, the config reloaded values are successfully retrieved using IOptionsSnapshot for console application.

@Kralizek / @jsauter Please review the above findings in #2 (for web application) and #3 (console application), and confirm if this issue could be closed.

Thanks,
Ashish

from aws-dotnet-extensions-configuration.

github-actions avatar github-actions commented on August 17, 2024

This issue has not received a response in 5 days. If you want to keep this issue open, please just leave a comment below and auto-close will be canceled.

from aws-dotnet-extensions-configuration.

github-actions avatar github-actions commented on August 17, 2024

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

from aws-dotnet-extensions-configuration.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.