You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jan 19, 2024. It is now read-only.
Describe the bug
We have a Single Application that needs to send emails for Multiple BU's. Unfortunately, due to how the ETClient is designed/implemented, Creating Multiple ETClient's as a singleton causes them to fight with each other when the OAuth Access Token is refreshed ( most likely due to the static members being used ). This means that we are unable to follow best practices and cache the OAuth Tokens using this provided library and instead must request a new OAuth Token on every request potentially hitting a rate limit and experience a performance impact due to the OAuth web request.
To Reproduce
Below is a simple Unit Test to reproduce the issue. Simply wait for the token refresh to occur.
usingSystem;usingSystem.Collections.Generic;usingSystem.Collections.Specialized;usingSystem.Diagnostics;usingSystem.Linq;usingSystem.Threading;usingFuelSDK;usingNUnit.Framework;namespaceETClientThreadingBug{publicstaticclassSubscriberProperties{publicconststringEmailAddress="Email Address";publicconststringFullName="Full Name";publicconststringFirstName="First Name";publicconststringLastName="Last Name";}[TestFixture]publicclassTests{[Test]publicvoidSingleEtClientSingletonWorksFineOnTokenRefresh(){varetClientOneBca=CreateEtClientOne();IList<Tuple<ETClient,int>>etClients=newList<Tuple<ETClient,int>>{newTuple<ETClient,int>(etClientOneBca,OneListId),};while(true){varetClientToUse=etClients[0];DoWork(etClientToUse);}}[Test]publicvoidDoubleEtClientSingletonFailsOnTokenRefresh(){varetClientOneBca=CreateEtClientOne();varetClientTwoBcom=CreateEtClientTwo();IList<Tuple<ETClient,int>>etClients=newList<Tuple<ETClient,int>>{newTuple<ETClient,int>(etClientOneBca,OneListId),newTuple<ETClient,int>(etClientTwoBcom,TwoListId)};while(true){varrandom=(DateTime.Now.Ticks%2)==0L?0:1;varetClientToUse=etClients[0];DoWork(etClientToUse);}}privatevoidDoWork(Tuple<ETClient,int>etClientToUse){varemailAddress="[email protected]";varsubscriber=newETSubscriber{AuthStub=etClientToUse.Item1,SubscriberKey=emailAddress,EmailAddress=emailAddress,Lists=newSubscriberList[]{newETSubscriberList{ID=etClientToUse.Item2,IDSpecified=true}},Attributes=newFuelSDK.Attribute[]{newETProfileAttribute{Name=SubscriberProperties.EmailAddress,Value=emailAddress},newETProfileAttribute{Name=SubscriberProperties.FullName,Value="boby dehop"},newETProfileAttribute{Name=SubscriberProperties.FirstName,Value="boby"},newETProfileAttribute{Name=SubscriberProperties.LastName,Value="dehop"}}};Console.WriteLine($"====================================================");Console.WriteLine($"Error OrgId: {etClientToUse.Item1.OrganizationId}");Console.WriteLine($"Error AuthToken: {etClientToUse.Item1.AuthToken}");Console.WriteLine($"Error InternalAuthToken: {etClientToUse.Item1.InternalAuthToken}");Console.WriteLine($"====================================================");varpostReturn=subscriber.Post();vardidItWork=postReturn.Status;//dws: check for specific error (already exists) on create//dws: there should be a better way to do this, this is what SF has in their sample codeif(postReturn.Results.Any()&&postReturn.Results[0].ErrorCode==12014){varpatchReturn=subscriber.Patch();didItWork=patchReturn.Status;if(!didItWork){// AddErrorResult(listId.ToString(), patchReturn.Results[0]);// Log.Error(GetErrorMessages() + $"Uploading subscriber information {customer.EmailAddress} to Exact Target list {listId} for site #{siteId}");Debug.WriteLine($"====================================================");Debug.WriteLine($"Error OrgId: {etClientToUse.Item1.OrganizationId}");Debug.WriteLine($"Error AuthToken: {etClientToUse.Item1.AuthToken}");Debug.WriteLine($"Error InternalAuthToken: {etClientToUse.Item1.InternalAuthToken}");Debug.WriteLine($"====================================================");}}else{if(!didItWork){Debug.WriteLine($"====================================================");Debug.WriteLine($"Error OrgId: {etClientToUse.Item1.OrganizationId}");Debug.WriteLine($"Error AuthToken: {etClientToUse.Item1.AuthToken}");Debug.WriteLine($"Error InternalAuthToken: {etClientToUse.Item1.InternalAuthToken}");Debug.WriteLine($"====================================================");}}Thread.Sleep(5000);}privateintOneListId=5555;privateETClientCreateEtClientOne(){varsettings=newNameValueCollection{{"clientId","xx"},{"clientSecret","xx"},{"authEndPoint","https://mc1cglt-xx.auth.marketingcloudapis.com"},{"useOAuth2Authentication","true"},{"accountId","xx"}};returnnewETClient(settings);}privateintTwoListId=5556;privateETClientCreateEtClientTwo(){varsettings=newNameValueCollection{{"clientId","xxxx"},{"clientSecret","xxxx"},{"authEndPoint","https://mc1cglt-xxxx.auth.marketingcloudapis.com"},{"useOAuth2Authentication","true"},{"accountId","xxxx"}};returnnewETClient(settings);}}}
Expected behavior
ETClient should be able to allow OAuth Access Token caching correctly across multiple ETClients for applications that need to communicate with multiple BU's.
Screenshots
N/A
Environment
SFMC.FueldSDK 1.3.0
.NET Framework version 4.7.1
The bug has the severity
Critical: The defect affects critical functionality or critical data. It does not have a workaround.
Major: The defect affects major functionality or major data. It has a workaround but is not obvious and is difficult.
Minor: The defect affects minor functionality or non-critical data. It has an easy workaround.
Trivial: The defect does not affect functionality or data. It does not even need a workaround. It does not impact productivity or efficiency. It is merely an inconvenience.
The text was updated successfully, but these errors were encountered:
Describe the bug
We have a Single Application that needs to send emails for Multiple BU's. Unfortunately, due to how the ETClient is designed/implemented, Creating Multiple ETClient's as a singleton causes them to fight with each other when the OAuth Access Token is refreshed ( most likely due to the static members being used ). This means that we are unable to follow best practices and cache the OAuth Tokens using this provided library and instead must request a new OAuth Token on every request potentially hitting a rate limit and experience a performance impact due to the OAuth web request.
To Reproduce
Below is a simple Unit Test to reproduce the issue. Simply wait for the token refresh to occur.
Expected behavior
ETClient should be able to allow OAuth Access Token caching correctly across multiple ETClients for applications that need to communicate with multiple BU's.
Screenshots
N/A
Environment
The bug has the severity
The text was updated successfully, but these errors were encountered: