Giter VIP home page Giter VIP logo

dotnet-client's People

Contributors

chillaq avatar israphel avatar mmelograno avatar nicozelaya avatar sanzmauro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dotnet-client's Issues

feature flags treatment always keeping the initial value

.Net version

.net 6

Library Version

Every version after 7.4.3

Issue

Every version past 7.4.3 seems to never get an updated value of the treatment. It always keeps the value that was fetched initially no matter the value of FeaturesRefreshRate in the configuration.

To demonstrate this I have the following console application code:

var config = new ConfigurationOptions
{
    FeaturesRefreshRate = 1
};

var factory = new SplitFactory("API_KEY", config);
var sdk = factory.Client();

try
{
    sdk.BlockUntilReady(10000);
}
catch (Exception ex)
{    
}

while(true)
{
    var treatment = sdk.GetTreatment("key", "feature");

    Console.WriteLine($"Value: {treatment}");

    Thread.Sleep(10000);
}

Repro steps

  1. Start the application and wait for the 1st treatment value to show in the console
  2. Change the value of the treatment
  3. Wait until the new value is displayed in the console

In version 7.4.3

We can see that the new value is fetched right away
image

In version 7.7.0(or any version past 7.4.3)

The new value is never fetched no matter how long we wait.
image

SDK was not ready in 10000 miliseconds

I am receiving SDK was not ready in 10000 miliseconds exception while making connection to split
I am using splitclient.BlockUntilReady(10000);

Increasing readyTimeout to 15000 ms did not resolve the issue

This is happening intermittently, I am not sure it is timeout or any other thing causing this issue.

Kindly, let me know what can be the resolution here?

Setting treatment percentage of traffic in the yml file

Hello,

I'm creating this issue because my team need to set the yml file for cases when split.io is off, but some of our splits have treatments with specific percentage, but currently it is not possible to be set using the dotnet-client sdk, so I raised a PR implementing this feature, can you please take a look that?

This is the PR: #87

Thank you very much!

Removal of segment item, is not refreshed by SelfRefreshingSegment

I seem to be experiencing a bug with either the library or your server side of things. Where the addition of a record in a segment will be picked up by the running application, but when removing an item is not registered until a new item is created in the segment.

All configuration is the default values and this has been reproduced multiple times, this issue does not occur for split rules, only for segment values.
Let me know if there is any other information I can provide to help diagnose the issue.

We are using library version: 6.3.6

Please see a subset of my logs below, with injected actions:

<add split rule item>
2021-11-30 04:58:03.591 +00:00 [Debug] Splitio.Services.SplitFetcher.Classes.SelfRefreshingSplitFetcher: split fetch before: 1638248140389, after: 1638248283095
2021-11-30 04:58:03.607 +00:00 [Debug] Splitio.Services.SplitFetcher.Classes.SelfRefreshingSplitFetcher: split fetch before: 1638248283095, after: 1638248283095

<remove split rule item>
2021-11-30 04:58:25.899 +00:00 [Debug] Splitio.Services.SplitFetcher.Classes.SelfRefreshingSplitFetcher: split fetch before: 1638248283095, after: 1638248304595
2021-11-30 04:58:25.908 +00:00 [Debug] Splitio.Services.SplitFetcher.Classes.SelfRefreshingSplitFetcher: split fetch before: 1638248304595, after: 1638248304595

<add segment item SOME_VALUE>
2021-11-30 04:58:56.627 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SegmentSdkApiClient: FetchSegmentChanges with name 'SEGMENT_NAME' took 28 milliseconds using uri '/api/segmentChanges/SEGMENT_NAME?since=1638247784807'
2021-11-30 04:58:56.627 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SelfRefreshingSegment: Segment SEGMENT_NAME - Added : SOME_VALUE
2021-11-30 04:58:56.627 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SelfRefreshingSegment: segment SEGMENT_NAME fetch before: 1638247784807, after: 1638248336164
2021-11-30 04:58:56.636 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SegmentSdkApiClient: FetchSegmentChanges with name 'SEGMENT_NAME' took 9 milliseconds using uri '/api/segmentChanges/SEGMENT_NAME?since=1638248336164'
2021-11-30 04:58:56.636 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SelfRefreshingSegment: segment SEGMENT_NAME fetch before: 1638248336164, after: 1638248336164

<remove segment item SOME_VALUE>
***crickets***

<add segment item SOME_OTHER_VALUE>
2021-11-30 05:05:31.075 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SegmentSdkApiClient: FetchSegmentChanges with name 'SEGMENT_NAME' took 66 milliseconds using uri '/api/segmentChanges/SEGMENT_NAME?since=1638248336164'
2021-11-30 05:05:31.075 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SelfRefreshingSegment: Segment SEGMENT_NAME - Added : SOME_OTHER_VALUE
2021-11-30 05:05:31.075 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SelfRefreshingSegment: Segment SEGMENT_NAME - Removed : SOME_VALUE
2021-11-30 05:05:31.075 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SelfRefreshingSegment: segment SEGMENT_NAME fetch before: 1638248336164, after: 1638248729802
2021-11-30 05:05:31.095 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SegmentSdkApiClient: FetchSegmentChanges with name 'SEGMENT_NAME' took 19 milliseconds using uri '/api/segmentChanges/SEGMENT_NAME?since=1638248729802'
2021-11-30 05:05:31.095 +00:00 [Debug] Splitio.Services.SegmentFetcher.Classes.SelfRefreshingSegment: segment SEGMENT_NAME fetch before: 1638248729802, after: 1638248729802

Thread leak, continuously growing threadpool with splitio initialized

For the last several weeks we noticed that the number of active threads in the thread pool will continuously grow when we have splitio initialized. This is most interestingly happening when our system is idle and not serving any traffic. The problem is that when we start to serve traffic and our number of active threads is larger than the minthreads setting, we are seeing long queues pile up for serving requests.
This seems to indicate that something in splitIO is creating threads and never properly releasing them.
You can see this happening in the image below over the course of 24 hours without serving any other traffic
image

If left on long enough without a restart we have even seen this number of threads grow to almost 500 active threads
image

When we first noticed this we were on the deprecated .net-core-client package so we upgraded to this version and also noticed that there was a fix recently for a memory leak #37 that we thought might help alleviate this issue but neither have fixed this issue of thread growth.

Newtonsoft.JSON v11.0.2 has CVE

Newtonsoft.Json prior to version 13.0.1 is vulnerable to Insecure Defaults due to improper handling of expressions with high nesting levels that lead to StackOverFlow exceptions or high CPU and RAM usage. Exploiting this vulnerability results in Denial Of Service (GHSA-5crp-9r3c-p9vr).

Please would you update your version? It's currently getting picked up on our security scans in our builds.

Support for Blazor WASM

Would like to be able to run the SDK client side in a Blazor WASM project. But it looks like you are using an unsupported feature of the HttpClientHandler in https://github.com/splitio/dotnet-client/blob/development/src/Splitio/CommonLibraries/SdkApiClient.cs. Namely AutomaticDecompression.

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Operation is not supported on this platform.
System.PlatformNotSupportedException: Operation is not supported on this platform.
at System.Net.Http.BrowserHttpHandler.set_AutomaticDecompression(DecompressionMethods value)
at System.Net.Http.HttpClientHandler.set_AutomaticDecompression(DecompressionMethods value)
at Splitio.CommonLibraries.SdkApiClient..ctor(String apiKey, Dictionary2 headers, String baseUrl, Int64 connectionTimeOut, Int64 readTimeout, ITelemetryRuntimeProducer telemetryRuntimeProducer) at Splitio.Services.SplitFetcher.Classes.SplitSdkApiClient..ctor(String apiKey, Dictionary2 headers, String baseUrl, Int64 connectionTimeOut, Int64 readTimeout, ITelemetryRuntimeProducer telemetryRuntimeProducer)
at Splitio.Services.Client.Classes.SelfRefreshingClient.BuildSdkApiClients()
at Splitio.Services.Client.Classes.SelfRefreshingClient..ctor(String apiKey, ConfigurationOptions config)
at Splitio.Services.Client.Classes.SplitFactory.BuildSplitClient()
at Splitio.Services.Client.Classes.SplitFactory.Client()
at Splitio.Services.Client.Classes.SplitFactory..ctor(String apiKey, ConfigurationOptions options)

You can do a check to see if the feature is available via HttpClientHandler.SupportsAutomaticDecompression, maybe a place to start.

Passing split logging messages to a custom ILogger instance is very confusing

There's alot to unravel to describe these difficulties. But I believe that the basic problems are as follows:

  1. ISplitLogger is not DI'd
  2. ISplitClient is not DI'd
  3. ISplitClient does not pass it's logger along to it's children
  4. ISplitFactory does not provide a method for defining a custom ISplitLogger when creating an ISplitClient

In order to help better understand what i'm trying to describe, here's the scenario I found myself in.

After experiencing some sporadic issues with Split only occurring when deployed, I wanted to get debug logs to see if there were any clues. My app uses a custom Microsoft.Extensions.Logging.ILogger implementation to handle pushing logging messages where we need them to go and for handling logging levels and all that - logging messages that don't use that custom ILogger simply do not write and cannot be viewed. After going through dozens of trials and reading through the code several times, I found that I needed to do the following to get all of this to work.

  1. I needed to create a fake DI container for all of my dependencies that the ILogger relies on to be created
  2. I needed to add my own implementation of ILoggerFactory that returns the ILogger defined above
  3. I needed to call SplitLoggerFactoryExtensions.AddSplitLogs() to setup my custom ILoggerFactory as the static one to use

Only then could I create the real DI container, and use SplitFactory to create and register a singleton instance of ISplitClient. It just doesn't integrate well with DI, more specifically the ILogger - everything else seems to be pretty self-contained and thus not an issue.

So.. i'll just go one-by-one here to describe the problems as I see them since it's alot to unravel.

ISplitLogger is not DI'd

I can understand why not everything is DI'able. But the problem here is that, when using a custom logger, in order to get split's library to output logs using that custom logger, it is a huge hassle, and not easy to figure out. You would assume that just providing your own implementation of Microsoft.Extensions.Logging.ILogger in a DI container would be enough as it is with most libraries, but that is not the case.

Because loggers are creating statically and use a static ILoggerFactory to generate the logger, in order to force it to use your logger, you must provide your own ILoggerFactory AND you must register it as "THE" logger factory that split will use by using SplitLoggerFactoryExtensions.AddSplitLogs(). This also MUST be done prior to the ISplitClient instance being generated.

ISplitClient is not DI'd

Again, I can understand why this may need to be available in a non-DI manner, but for this one in particular, I really do feel as though a DI'able implementation of ISplitClient (or really an implementation of a provider that inspects the config to determine what implementation to use) could easily be made, and options can be defined via the IOptions interface. The problem with it not being DI'd is that for apps using DI that require an ISplitClient, you really can only create one on demand as needed, or inject a singleton for the entire app.

ISplitClient does not pass it's logger along to it's children

So this is just confusing and doesn't make sense. If an instance of ISplitClient is created with an instance of ISplitLogger, that instance should be used for all child dependencies. It's not necessarily a problem as it is right now, but the changes that would need to be made to support the other problems would make this problem surface as well.

ISplitFactory does not provide a method for defining a custom ISplitLogger when creating an ISplitClient

This could easily be a workaround solution - just update the ISplitFactory.Client() method to have an optional ISplitLogger parameter that gets passed along.

But really, if ISplitClient was DI'd and it's resolver referenced SplitFactory.Create, it should pass along the registered ILogger along to be used as the ISplitLogger.

Initialization fails if computer name contains non-ASCII characters

Hi, we run into some issues when creating clients with computers with non-ASCII names (Danish, Japanese etc.) in computer names.

[ERR] Exception caught executing GET https://sdk.split.io/api/splitChanges?since=-1
System.Net.Http.HttpRequestException: Request headers must contain only ASCII characters.
at System.Net.Http.HttpConnection.WriteStringAsync(String s)
at System.Net.Http.HttpConnection.WriteHeadersAsync(HttpHeaders headers, String cookiesFromContainer)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Splitio.Services.Common.SplitioHttpClient.GetAsync(String url, Boolean cacheControlHeadersEnabled)

I believe this issue is caused by this line. Calling HttpUtility.HtmlEncode() here would fix the problem, but this also needs to be decoded on Split's backend. Can you take a look at it?

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.