Skip to content

Commit 35b0bed

Browse files
committed
Merge pull request #1720 from elastic/spike/dispose
Spike/dispose
2 parents 0300d7c + 0a9239c commit 35b0bed

26 files changed

+957
-781
lines changed

Diff for: src/Elasticsearch.Net/Auditing/Audit.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ public class Audit
1111
public string Path { get; internal set; }
1212
public Exception Exception { get; internal set; }
1313

14-
public Audit(AuditEvent type, DateTime occured)
14+
public Audit(AuditEvent type, DateTime started)
1515
{
1616
this.Event = type;
17-
this.Started = occured;
17+
this.Started = started;
1818
}
1919

2020
public override string ToString()
2121
{
2222
var took = Started - Ended;
23-
return $"Node: {Node?.Uri}, Event: {Event.GetStringValue()} NodeAlive: {Node?.IsAlive}, Took: {took.ToString()}";
23+
return $"Node: {Node?.Uri}, Event: {Event.GetStringValue()} NodeAlive: {Node?.IsAlive}, Took: {took}";
2424
}
2525
}
2626
}

Diff for: src/Elasticsearch.Net/Configuration/ConnectionConfiguration.cs

+21-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Specialized;
33
using System.ComponentModel;
4+
using System.Threading;
45

56
namespace Elasticsearch.Net
67
{
@@ -10,15 +11,16 @@ namespace Elasticsearch.Net
1011
/// </summary>
1112
public class ConnectionConfiguration : ConnectionConfiguration<ConnectionConfiguration>
1213
{
13-
public static TimeSpan DefaultTimeout = TimeSpan.FromMinutes(1);
14-
public static TimeSpan DefaultPingTimeout = TimeSpan.FromSeconds(2);
15-
public static TimeSpan DefaultPingTimeoutOnSSL = TimeSpan.FromSeconds(5);
14+
public static readonly TimeSpan DefaultTimeout = TimeSpan.FromMinutes(1);
15+
public static readonly TimeSpan DefaultPingTimeout = TimeSpan.FromSeconds(2);
16+
public static readonly TimeSpan DefaultPingTimeoutOnSSL = TimeSpan.FromSeconds(5);
1617

1718
/// <summary>
1819
/// ConnectionConfiguration allows you to control how ElasticsearchClient behaves and where/how it connects
1920
/// to elasticsearch
2021
/// </summary>
2122
/// <param name="uri">The root of the elasticsearch node we want to connect to. Defaults to http://localhost:9200</param>
23+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
2224
public ConnectionConfiguration(Uri uri = null)
2325
: this(new SingleNodeConnectionPool(uri ?? new Uri("http://localhost:9200")))
2426
{ }
@@ -47,13 +49,17 @@ public ConnectionConfiguration(IConnectionPool connectionPool, Func<ConnectionCo
4749
public ConnectionConfiguration(IConnectionPool connectionPool, IConnection connection, Func<ConnectionConfiguration, IElasticsearchSerializer> serializerFactory)
4850
: base(connectionPool, connection, serializerFactory)
4951
{ }
52+
5053
}
5154

5255
[Browsable(false)]
5356
[EditorBrowsable(EditorBrowsableState.Never)]
5457
public abstract class ConnectionConfiguration<T> : IConnectionConfigurationValues, IHideObjectMembers
5558
where T : ConnectionConfiguration<T>
5659
{
60+
private SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
61+
SemaphoreSlim IConnectionConfigurationValues.BootstrapLock => this._semaphore;
62+
5763
private TimeSpan _requestTimeout;
5864
TimeSpan IConnectionConfigurationValues.RequestTimeout => _requestTimeout;
5965

@@ -130,11 +136,10 @@ private static void DefaultApiCallHandler(IApiCallDetails status) { }
130136
BasicAuthenticationCredentials _basicAuthCredentials;
131137
BasicAuthenticationCredentials IConnectionConfigurationValues.BasicAuthenticationCredentials => _basicAuthCredentials;
132138

133-
protected IElasticsearchSerializer _serializer;
139+
private readonly IElasticsearchSerializer _serializer;
134140
IElasticsearchSerializer IConnectionConfigurationValues.Serializer => _serializer;
135141

136142
private readonly IConnectionPool _connectionPool;
137-
private readonly Func<T, IElasticsearchSerializer> _serializerFactory;
138143
IConnectionPool IConnectionConfigurationValues.ConnectionPool => _connectionPool;
139144

140145
private readonly IConnection _connection;
@@ -147,9 +152,9 @@ protected ConnectionConfiguration(IConnectionPool connectionPool, IConnection co
147152
{
148153
this._connectionPool = connectionPool;
149154
this._connection = connection ?? new HttpConnection();
150-
this._serializerFactory = serializerFactory ?? (c=>this.DefaultSerializer((T)this));
155+
serializerFactory = serializerFactory ?? (c=>this.DefaultSerializer((T)this));
151156
// ReSharper disable once VirtualMemberCallInContructor
152-
this._serializer = this._serializerFactory((T)this);
157+
this._serializer = serializerFactory((T)this);
153158

154159
this._requestTimeout = ConnectionConfiguration.DefaultTimeout;
155160
this._sniffOnConnectionFault = true;
@@ -308,6 +313,15 @@ public T BasicAuthentication(string userName, string password)
308313
/// <para>Note: HTTP pipelining must also be enabled in Elasticsearch for this to work properly.</para>
309314
/// </summary>
310315
public T EnableHttpPipelining(bool enabled = true) => Assign(a => a._enableHttpPipelining = enabled);
316+
317+
void IDisposable.Dispose() => this.DisposeManagedResources();
318+
319+
protected virtual void DisposeManagedResources()
320+
{
321+
this._connectionPool?.Dispose();
322+
this._connection?.Dispose();
323+
this._semaphore?.Dispose();
324+
}
311325
}
312326
}
313327

Diff for: src/Elasticsearch.Net/Configuration/IConnectionConfigurationValues.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
using System;
22
using System.Collections.Specialized;
3+
using System.Threading;
34

45
namespace Elasticsearch.Net
56
{
6-
public interface IConnectionConfigurationValues
7+
public interface IConnectionConfigurationValues : IDisposable
78
{
9+
/// <summary> Provides a semaphoreslim to transport implementations that need to limit access to a resource</summary>
10+
SemaphoreSlim BootstrapLock { get; }
11+
812
/// <summary> The connection pool to use when talking with elasticsearch </summary>
913
IConnectionPool ConnectionPool { get; }
1014

Diff for: src/Elasticsearch.Net/Connection/HttpConnection.cs

+4
Original file line numberDiff line numberDiff line change
@@ -194,5 +194,9 @@ private void HandleException<TReturn>(ResponseBuilder<TReturn> builder, WebExcep
194194
builder.Stream = response.GetResponseStream();
195195
}
196196
}
197+
198+
void IDisposable.Dispose() => this.DisposeManagedResources();
199+
200+
protected virtual void DisposeManagedResources() { }
197201
}
198202
}

Diff for: src/Elasticsearch.Net/Connection/IConnection.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
using System.Threading.Tasks;
1+
using System;
2+
using System.Threading.Tasks;
23

34
namespace Elasticsearch.Net
45
{
5-
public interface IConnection
6+
public interface IConnection : IDisposable
67
{
78
Task<ElasticsearchResponse<TReturn>> RequestAsync<TReturn>(RequestData requestData)
89
where TReturn : class;

Diff for: src/Elasticsearch.Net/ConnectionPool/IConnectionPool.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Elasticsearch.Net
55
{
6-
public interface IConnectionPool
6+
public interface IConnectionPool : IDisposable
77
{
88
/// <summary>
99
/// Returns a readonly constant view of all the nodes in the cluster, this might involve creating copies of the nodes e.g

Diff for: src/Elasticsearch.Net/ConnectionPool/SingleNodeConnectionPool.cs

+4
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,9 @@ public SingleNodeConnectionPool(Uri uri, IDateTimeProvider dateTimeProvider = nu
2929
}
3030

3131
public IEnumerable<Node> CreateView(Action<AuditEvent, Node> audit = null) => this.Nodes;
32+
33+
void IDisposable.Dispose() => this.DisposeManagedResources();
34+
35+
protected virtual void DisposeManagedResources() { }
3236
}
3337
}

Diff for: src/Elasticsearch.Net/ConnectionPool/SniffingConnectionPool.cs

+5
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,10 @@ public override IEnumerable<Node> CreateView(Action<AuditEvent, Node> audit = nu
7373
}
7474
}
7575

76+
protected override void DisposeManagedResources()
77+
{
78+
this._readerWriter?.Dispose();
79+
base.DisposeManagedResources();
80+
}
7681
}
7782
}

Diff for: src/Elasticsearch.Net/ConnectionPool/StaticConnectionPool.cs

+3
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,8 @@ public virtual IEnumerable<Node> CreateView(Action<AuditEvent, Node> audit = nul
9797
}
9898
}
9999

100+
void IDisposable.Dispose() => this.DisposeManagedResources();
101+
102+
protected virtual void DisposeManagedResources() { }
100103
}
101104
}

Diff for: src/Elasticsearch.Net/Elasticsearch.Net.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<WarningLevel>4</WarningLevel>
2424
<UseVSHostingProcess>false</UseVSHostingProcess>
2525
<Prefer32Bit>false</Prefer32Bit>
26+
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
2627
</PropertyGroup>
2728
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
2829
<DebugType>pdbonly</DebugType>
@@ -54,6 +55,7 @@
5455
<ItemGroup>
5556
<Compile Include="Configuration\RequestConfiguration.cs" />
5657
<Compile Include="Exceptions\UnexpectedElasticsearchClientException.cs" />
58+
<Compile Include="GlobalSuppressions.cs" />
5759
<Compile Include="Transport\Pipeline\PipelineException.cs" />
5860
<Compile Include="Connection\HttpMethod.cs" />
5961
<Compile Include="Auditing\Audit.cs" />

Diff for: src/Elasticsearch.Net/ElasticsearchClient.cs

+2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ public partial class ElasticsearchClient : IElasticsearchClient
1616
protected ITransport<IConnectionConfigurationValues> Transport { get; set; }
1717

1818
/// <summary>Instantiate a new low level elasticsearch client to http://localhost:9200</summary>
19+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
1920
public ElasticsearchClient() : this(new Transport<IConnectionConfigurationValues>(new ConnectionConfiguration())) { }
2021

2122
/// <summary>Instantiate a new low level elasticsearch client using the specified settings</summary>
23+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
2224
public ElasticsearchClient(IConnectionConfigurationValues settings) : this(new Transport<IConnectionConfigurationValues>(settings ?? new ConnectionConfiguration())) { }
2325

2426
/// <summary>

Diff for: src/Elasticsearch.Net/GlobalSuppressions.cs

3.34 KB
Binary file not shown.

Diff for: src/Elasticsearch.Net/Transport/ITransport.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
using System;
12
using System.Threading.Tasks;
23

34
namespace Elasticsearch.Net
45
{
5-
public interface ITransport<out TConnectionSettings> where TConnectionSettings : IConnectionConfigurationValues
6+
public interface ITransport<out TConnectionSettings>
7+
where TConnectionSettings : IConnectionConfigurationValues
68
{
79
TConnectionSettings Settings { get; }
810

0 commit comments

Comments
 (0)