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
Operating system version: Windows 11 Home Single Language 22H2
Description of the problem including expected versus actual behavior:
The IElasticClient throws "The semaphore has been disposed" error if its initialization is in if-else block or placed on a function
Steps to reproduce:
Add the following Program.cs in a Web API project
using Elasticsearch.Net;
using Nest;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
if (true)
{
using var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
using var connectionSettings = new ConnectionSettings(pool);
var client = new ElasticClient(connectionSettings);
builder.Services.AddSingleton<IElasticClient>(client);
}
var app = builder.Build();
app.UseAuthorization();
app.MapControllers();
app.Run();
Use the following block of WeatherForecastController.cs
using APIResearch.Models;
using Microsoft.AspNetCore.Mvc;
using Nest;
namespace APIResearch.Controllers
{
public class City
{
public int? id { get; set; }
public long? cityId { get; set; }
public string cityCode { get; set; }
public string countryCode { get; set; }
public float? latitude { get; set; }
public float? longitude { get; set; }
public string areaType { get; set; }
public string areaGeometry { get; set; }
public string supplierCityCode { get; set; }
public bool isIndonesia { get; set; }
public int? priority { get; set; }
[GeoPoint(Name = "location")]
public Location location { get; set; }
public string cityName { get; set; }
public string countryName { get; set; }
public string language { get; set; }
}
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
private readonly IElasticClient _elasticClient;
public WeatherForecastController(IElasticClient elasticClient) => _elasticClient = elasticClient;
[HttpGet]
public async Task<IEnumerable<WeatherForecast>> Get()
{
try
{
var cityName = "Jakarta";
var indexName = "jarvis_api_cities_dev";
var mustQuery = cityName.Split('*')
.Select(q => new WildcardQuery { Field = Infer.Field<City>(f => f.cityName), Value = $"{q}*", Rewrite = MultiTermQueryRewrite.ScoringBoolean })
.Select(dummy => (QueryContainer)dummy).ToList();
var searchRequest = new SearchRequest(indexName)
{
Query = new BoolQuery { Must = mustQuery }
};
var asd = _elasticClient.Search<City>(searchRequest);
}
catch (Exception e)
{
//_logger.Error(e, "text");
}
}
}
}
Run the project
Expected behavior
The strange thing is, if I write the Program.cs without using any if-else block like the following:
using Elasticsearch.Net;
using Nest;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
using var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
using var connectionSettings = new ConnectionSettings(pool);
var client = new ElasticClient(connectionSettings);
builder.Services.AddSingleton<IElasticClient>(client);
var app = builder.Build();
app.UseAuthorization();
app.MapControllers();
app.Run();
the exception doesn't occur.
Provide DebugInformation (if relevant):
System.ObjectDisposedException
HResult=0x80131622
Message=The semaphore has been disposed.
Source=System.Private.CoreLib
StackTrace:
at System.Threading.SemaphoreSlim.CheckDispose() in //src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs:line 923
at System.Threading.SemaphoreSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) in //src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs:line 292
at System.Threading.SemaphoreSlim.Wait(TimeSpan timeout) in /_/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs:line 217
at Elasticsearch.Net.RequestPipeline.FirstPoolUsage(SemaphoreSlim semaphore)
at Elasticsearch.Net.Transport`1.Request[TResponse](HttpMethod method, String path, PostData data, IRequestParameters requestParameters)
at Nest.ElasticClient.Search[TDocument](ISearchRequest request)
at APIResearch.Controllers.WeatherForecastController.d__3.MoveNext() in C:\Users\bobby\source\repos\XXX\XXX.Mobile\APIResearch\Controllers\WeatherForecastController.cs:line 95
This exception was originally thrown at this call stack:
System.Threading.SemaphoreSlim.CheckDispose() in SemaphoreSlim.cs
System.Threading.SemaphoreSlim.Wait(int, System.Threading.CancellationToken) in SemaphoreSlim.cs
System.Threading.SemaphoreSlim.Wait(System.TimeSpan) in SemaphoreSlim.cs
Elasticsearch.Net.RequestPipeline.FirstPoolUsage(System.Threading.SemaphoreSlim)
Elasticsearch.Net.Transport.Request(Elasticsearch.Net.HttpMethod, string, Elasticsearch.Net.PostData, Elasticsearch.Net.IRequestParameters)
Nest.ElasticClient.Search(Nest.ISearchRequest)
APIResearch.Controllers.WeatherForecastController.Get() in WeatherForecastController.cs
Is there any mistake I made on the initialization?
The text was updated successfully, but these errors were encountered:
@BobbyFerdi Although disposable, you shouldn't have the using declaration on SingleNodeConnectionPool and ConnectionSettings. These should be treated as singletons for the life of the application.
In this case, the reason for the differing behaviour is down to how the using declaration is scoped. In the first example, the using declaration is scoped to your if conditional block. Once that block ends, before var app = builder.Build();, these objects are disposed of, even though they are used by the ElasticClient added to the service provider. In your working example, there is no conditional block, so the using declaration is scoped to include all of the code, and they do not get disposed of until the application ends.
The solution here is to not apply the using keyword to these. Does that make sense?
Uh oh!
There was an error while loading. Please reload this page.
NEST/Elasticsearch.Net version: 7.17.5
Elasticsearch version: 7.17.12
.NET runtime version: 6.0.22
Operating system version: Windows 11 Home Single Language 22H2
Description of the problem including expected versus actual behavior:
The IElasticClient throws "The semaphore has been disposed" error if its initialization is in if-else block or placed on a function
Steps to reproduce:
Expected behavior
The strange thing is, if I write the Program.cs without using any if-else block like the following:
the exception doesn't occur.
Provide
DebugInformation
(if relevant):System.ObjectDisposedException
HResult=0x80131622
Message=The semaphore has been disposed.
Source=System.Private.CoreLib
StackTrace:
at System.Threading.SemaphoreSlim.CheckDispose() in //src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs:line 923
at System.Threading.SemaphoreSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) in //src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs:line 292
at System.Threading.SemaphoreSlim.Wait(TimeSpan timeout) in /_/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs:line 217
at Elasticsearch.Net.RequestPipeline.FirstPoolUsage(SemaphoreSlim semaphore)
at Elasticsearch.Net.Transport`1.Request[TResponse](HttpMethod method, String path, PostData data, IRequestParameters requestParameters)
at Nest.ElasticClient.Search[TDocument](ISearchRequest request)
at APIResearch.Controllers.WeatherForecastController.d__3.MoveNext() in C:\Users\bobby\source\repos\XXX\XXX.Mobile\APIResearch\Controllers\WeatherForecastController.cs:line 95
This exception was originally thrown at this call stack:
System.Threading.SemaphoreSlim.CheckDispose() in SemaphoreSlim.cs
System.Threading.SemaphoreSlim.Wait(int, System.Threading.CancellationToken) in SemaphoreSlim.cs
System.Threading.SemaphoreSlim.Wait(System.TimeSpan) in SemaphoreSlim.cs
Elasticsearch.Net.RequestPipeline.FirstPoolUsage(System.Threading.SemaphoreSlim)
Elasticsearch.Net.Transport.Request(Elasticsearch.Net.HttpMethod, string, Elasticsearch.Net.PostData, Elasticsearch.Net.IRequestParameters)
Nest.ElasticClient.Search(Nest.ISearchRequest)
APIResearch.Controllers.WeatherForecastController.Get() in WeatherForecastController.cs
Is there any mistake I made on the initialization?
The text was updated successfully, but these errors were encountered: