oci-dotnet-sdk icon indicating copy to clipboard operation
oci-dotnet-sdk copied to clipboard

Resource temporarily unavailable

Open fernandocristan opened this issue 11 months ago • 6 comments

Hello, recently i got this error on my API. It happens occasionally.

I believe it is the problem related to creating too many instances of HttpClient instead of using the services.AddHttpClient configuration and getting the HttpClient via dependency injection.

The stack trace seems to indicate this:

StackTrace:    at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
   at Oci.Common.Http.RestClient.HttpSend(HttpRequestMessage httpRequest, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at Oci.ObjectstorageService.ObjectStorageClient.CreateBucket(CreateBucketRequest request, RetryConfiguration retryConfiguration, CancellationToken cancellationToken, HttpCompletionOption completionOption)
   at LogSistemas.Domynus.Application.Core.Services.File.OracleObjectStorageService.ValidateBucket(String bucketName) in /home/runner/work/domynus-api/domynus-api/src/LogSistemas.Domynus.Application.Core/Services/File/OracleObjectStorageService.cs:line 261
   at LogSistemas.Domynus.Application.Core.Services.File.OracleObjectStorageService.DownloadFile(String key, String bucketName) in /home/runner/work/domynus-api/domynus-api/src/LogSistemas.Domynus.Application.Core/Services/File/OracleObjectStorageService.cs:line 106
   at 

I've received this error too: Name or service not known (objectstorage.sa-saopaulo-1.oraclecloud.com:443), under the same conditions, it rarely occurs.

Stack trace

StackTrace:    at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(HttpRequestMessage request)
   at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)
   at Oci.Common.Http.RestClient.HttpSend(HttpRequestMessage httpRequest, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at Oci.ObjectstorageService.ObjectStorageClient.CreateBucket(CreateBucketRequest request, RetryConfiguration retryConfiguration, CancellationToken cancellationToken, HttpCompletionOption completionOption)
   at LogSistemas.Domynus.Application.Core.Services.File.OracleObjectStorageService.ValidateBucket(String bucketName) in /home/runner/work/domynus-api/domynus-api/src/LogSistemas.Domynus.Application.Core/Services/File/OracleObjectStorageService.cs:line 260

I looked in the documentation to see how I could configure it to use services.AddHttpClient but I couldn't find it.

Any suggestions for how to get around this?

fernandocristan avatar Dec 23 '24 14:12 fernandocristan

Hello @fernandocristan Can you please share the code snippet you are currently using? Are creating a new client for each request by any chance? If so, can you re-use the same client for your API calls?

github-anurag avatar Dec 23 '24 16:12 github-anurag

Hello @fernandocristan Can you please share the code snippet you are currently using? Are creating a new client for each request by any chance? If so, can you re-use the same client for your API calls?

Hello, sure.

OracleObjectStorageService.txt

This is the lifecycle configuration

services.AddScoped<IFileCloudStorageService, OracleObjectStorageService>();

Service creation is through dependency injection.

fernandocristan avatar Dec 23 '24 19:12 fernandocristan

Packages

  • OCI.DotNetSDK.Common 51.1.0
  • OCI.DotNetSDK.Filestorage 51.1.0
  • OCI.DotNetSDK.Objectstorage 51.1.0

fernandocristan avatar Dec 23 '24 19:12 fernandocristan

@fernandocristan We create one http client per service client, as each service client may have different http options, can you make sure you are not creating new clients on each request and also try upgrading to the latest OCI Dotnet SDK to see if it resolves your issue?

github-anurag avatar Feb 07 '25 17:02 github-anurag

@fernandocristan We create one http client per service client, as each service client may have different http options, can you make sure you are not creating new clients on each request and also try upgrading to the latest OCI Dotnet SDK to see if it resolves your issue?

Yes, in each request are created a new instance of OracleObjectStorageService since his lifetime is scoped, inside this service are created oracle client

fernandocristan avatar Feb 12 '25 13:02 fernandocristan

Hello, i have changed my oracle service that creates the client to singleton lifetime. But i still receive this error:

Either the bucket '[bucket-name]' in namespace '[namespace]' already exists or you are not authorized to create it

I know what the error indicates, but if the process that raised this error is repeated, it works. The bucket exists in the namespace. This error occurs occasionally, but not always.

Any suggestions on what I can do?

before upload file, i check if bucket exists with this code and its here that occurs the problem, because in _client.HeadBucket occurs exception. I receive this log Bucket {bucketName} not found (Oracle)


private async Task ValidateBucket(string bucketName)
{
    //https://docs.oracle.com/en-us/iaas/api/#/en/objectstorage/20160918/Bucket/GetBucket
    HeadBucketRequest headBucketRequest = new()
    {
        NamespaceName = _nameSpace,
        BucketName = bucketName,
    };
    HeadBucketResponse getResponse;
    try
    {
        getResponse = await _client.HeadBucket(headBucketRequest);
    }
    catch (Exception)
    {
        _logger.LogWarning("Bucket {bucketName} not found (Oracle)", bucketName);

        //https://docs.oracle.com/en-us/iaas/api/#/en/objectstorage/20160918/Bucket/CreateBucket
        CreateBucketRequest createBucketRequest = new()
        {
            NamespaceName = _nameSpace,
            CreateBucketDetails = new CreateBucketDetails
            {
                Name = bucketName,
                CompartmentId = _compartmentId
            }
        };
        CreateBucketResponse createResponse = await _client.CreateBucket(createBucketRequest);
        if (string.IsNullOrEmpty(createResponse.Bucket.Id))
        {
            _logger.LogError("Bucket not created. Response (oracle): {@oracleResponse}", createResponse);
            throw new DomynusException(nameof(ErrorCodes.ME0095), ErrorCodes.ME0095.Format("Oracle"), createResponse);
        }

        _logger.LogWarning("Bucket created. Response (oracle): {@oracleResponse}", createResponse);
    }
}

fernandocristan avatar Apr 17 '25 11:04 fernandocristan