Multiple error at GetOrders & GetOrderItems
Hello, I have the following situation with the 1.7.1 version:
- I have a job which calls sp-api for getting orders and order items for multiple stores, but I am waiting for one store to finish to start with another one
- the only concurent requests are for getting orders, I am making 2 request, one for FBM and one for FBA for each store
- I handle the AmazonConnection with a ConcurentDictionary, having the key as a unique string for each store. This dictionary is in a singleton class
builder.Services.AddSingleton<IAmazonConnectionManager, AmazonConnectionManager>();
public interface IAmazonConnectionManager
{
AmazonConnection GetOrCreateConnection(string apiKey, AmaCredential.AmazonCredential amazonCredential);
}
public class AmazonConnectionManager : IAmazonConnectionManager
{
private readonly ConcurrentDictionary<string, (AmazonConnection connection, int credentialHash)> _connections = new();
public AmazonConnection GetOrCreateConnection(string apiKey, AmaCredential.AmazonCredential amazonCredential)
{
int credentialHash = amazonCredential.GetHashCode();
var credential = new AmazonCredential
{
AccessKey = amazonCredential.AccessKey,
SecretKey = amazonCredential.SecretKey,
RoleArn = amazonCredential.RoleArn,
ClientId = amazonCredential.ClientId,
ClientSecret = amazonCredential.ClientSecret,
RefreshToken = amazonCredential.RefreshToken,
MarketPlace = MarketPlace.GetMarketPlaceByID(amazonCredential.MarketPlace),
SellerID = amazonCredential.SellerId
};
var connectionInfo = _connections.AddOrUpdate(apiKey,
// If key does not exist, create new connection info
key => new()
{
connection = new AmazonConnection(credential),
credentialHash = credentialHash
},
//Check if the hash already saved in dictionary is the same with the credential received. If not, overwrite the connection in dictionary.
//The credentials will change every 6 months due to Amazon policy of LWA token rotation
(key, existingInfo) => existingInfo.credentialHash != credentialHash ? new()
{
connection = new AmazonConnection(credential),
credentialHash = credentialHash
} : existingInfo
);
return connectionInfo.connection;
}
}
During the job run, from time to time, I get the following errors just for one store(the lines with orange are the same store)
Errors:
Index was outside the bounds of the array.
An item with the same key has already been added. Key: LastUpdatedAfter
An item with the same key has already been added. Key: LastUpdatedAfter
Error getting LWA Access Token
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Net.Http.Headers.HttpHeaders.ReadStoreValues[T](Span`1 values, Object storeValue, HttpHeaderParser parser, Int32& currentIndex)
at System.Net.Http.Headers.HttpHeaders.GetStoreValuesAsStringOrStringArray(HeaderDescriptor descriptor, Object sourceValues, String& singleValue, String[]& multiValue)
at System.Net.Http.Headers.HttpHeaders.GetHeaderString(HeaderDescriptor descriptor)
at RestSharp.RestResponse.<>c__DisplayClass0_0.<<FromHttpResponse>g__GetDefaultResponse|0>d.MoveNext()
--- End of stack trace from previous location ---
at RestSharp.RestResponse.<>c__DisplayClass0_0.<<FromHttpResponse>g__GetDefaultResponse|0>d.MoveNext()
--- End of stack trace from previous location ---
at RestSharp.RestResponse.FromHttpResponse(HttpResponseMessage httpResponse, RestRequest request, Encoding encoding, CookieCollection cookieCollection, CalculateResponseStatus calculateResponseStatus, CancellationToken cancellationToken)
at RestSharp.RestClient.ExecuteAsync(RestRequest request, CancellationToken cancellationToken)
at FikaAmazonAPI.AmazonSpApiSDK.Runtime.LWAClient.GetAccessTokenAsync(CancellationToken cancellationToken)
Error getting LWA Access Token
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Net.Http.Headers.HttpHeaders.ReadStoreValues[T](Span`1 values, Object storeValue, HttpHeaderParser parser, Int32& currentIndex)
at System.Net.Http.Headers.HttpHeaders.GetStoreValuesAsStringOrStringArray(HeaderDescriptor descriptor, Object sourceValues, String& singleValue, String[]& multiValue)
at System.Net.Http.Headers.HttpHeaders.GetHeaderString(HeaderDescriptor descriptor)
at RestSharp.RestResponse.<>c__DisplayClass0_0.<<FromHttpResponse>g__GetDefaultResponse|0>d.MoveNext()
--- End of stack trace from previous location ---
at RestSharp.RestResponse.<>c__DisplayClass0_0.<<FromHttpResponse>g__GetDefaultResponse|0>d.MoveNext()
--- End of stack trace from previous location ---
at RestSharp.RestResponse.FromHttpResponse(HttpResponseMessage httpResponse, RestRequest request, Encoding encoding, CookieCollection cookieCollection, CalculateResponseStatus calculateResponseStatus, CancellationToken cancellationToken)
at RestSharp.RestClient.ExecuteAsync(RestRequest request, CancellationToken cancellationToken)
at FikaAmazonAPI.AmazonSpApiSDK.Runtime.LWAClient.GetAccessTokenAsync(CancellationToken cancellationToken)
Is this because I am making in the same time 2 requests for the same endpoint? And why is not failing for all the stores in this case?
Yes, it's not possible to make two concurrent connections to Amazon from the same Connection.
We've resolved this using a shared semaphore.
e.g.
if (await _semaphoreSlim.WaitAsync(30000, cancellationToken))
{
// Some call the the connection
}
The answer to why does this only happen some times is "timing".