Skip to content

Commit

Permalink
Merge pull request #295 from ali-ince/1.6-split-metrics-implementation
Browse files Browse the repository at this point in the history
Split metrics implementation
  • Loading branch information
ali-ince authored Apr 25, 2018
2 parents ed05381 + 1eab556 commit fd5d863
Show file tree
Hide file tree
Showing 24 changed files with 136 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using System.Threading.Tasks;
using FluentAssertions;
using Neo4j.Driver.Internal.IO;
using Neo4j.Driver.Internal.Metrics;
using Neo4j.Driver.V1;
using Xunit;
using Xunit.Abstractions;
Expand Down Expand Up @@ -130,7 +131,7 @@ public void ShouldCloseIdleForTooLongConns(int sessionCount)
// Given
using (var driver = GraphDatabase.Driver("bolt://127.0.0.1:7687", AuthToken, new Config
{
DriverMetricsEnabled = true,
MetricsFactory = new DefaultMetricsFactory(),
ConnectionIdleTimeout = TimeSpan.Zero // enable but always timeout idle connections
}))
{
Expand Down Expand Up @@ -163,7 +164,7 @@ public void SoakRun(int threadCount)
{
var driver = GraphDatabase.Driver(ServerEndPoint, AuthToken, new Config
{
DriverMetricsEnabled = true,
MetricsFactory = new DefaultMetricsFactory(),
ConnectionTimeout = Config.InfiniteInterval,
EncryptionLevel = EncryptionLevel.Encrypted
});
Expand Down Expand Up @@ -208,7 +209,7 @@ public async void SoakRunAsync(int threadCount)
{
var driver = GraphDatabase.Driver(ServerEndPoint, AuthToken, new Config
{
DriverMetricsEnabled = true,
MetricsFactory = new DefaultMetricsFactory(),
ConnectionTimeout = Config.InfiniteInterval,
MaxConnectionPoolSize = 500,
EncryptionLevel = EncryptionLevel.Encrypted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<DotNetCliToolReference Include="dotnet-xunit" Version="$(XunitVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Neo4j.Driver.Metrics\Neo4j.Driver.Metrics.csproj" />
<ProjectReference Include="..\Neo4j.Driver\Neo4j.Driver.csproj" />
</ItemGroup>
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using FluentAssertions;
using Neo4j.Driver.IntegrationTests.Internals;
using Neo4j.Driver.Internal;
using Neo4j.Driver.Internal.Metrics;
using Neo4j.Driver.V1;
using Xunit;
using Xunit.Abstractions;
Expand Down Expand Up @@ -138,7 +139,7 @@ public async void SoakRunAsync(int threadCount)
{
var driver = GraphDatabase.Driver(RoutingServer, AuthToken, new Config
{
DriverMetricsEnabled = true,
MetricsFactory = new DefaultMetricsFactory(),
ConnectionTimeout = Config.InfiniteInterval,
EncryptionLevel = EncryptionLevel.Encrypted,
MaxIdleConnectionPoolSize = 50,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using FluentAssertions;
using Neo4j.Driver.IntegrationTests.Internals;
using Neo4j.Driver.Internal;
using Neo4j.Driver.Internal.Metrics;
using Neo4j.Driver.V1;
using Xunit;
using Xunit.Abstractions;
Expand Down Expand Up @@ -130,7 +131,7 @@ public void SoakRunTests(int threadCount)
{
var driver = GraphDatabase.Driver(RoutingServer, AuthToken, new Config
{
DriverMetricsEnabled = true,
MetricsFactory = new DefaultMetricsFactory(),
ConnectionTimeout = Config.InfiniteInterval,
EncryptionLevel = EncryptionLevel.Encrypted,
MaxIdleConnectionPoolSize = 20,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private void SetupMonitoredDriver()
{
var config = new Config
{
DriverMetricsEnabled = true,
MetricsFactory = new DefaultMetricsFactory(),
ConnectionAcquisitionTimeout = TimeSpan.FromMinutes(5),
ConnectionTimeout = Config.InfiniteInterval,
MaxConnectionPoolSize = 50,
Expand All @@ -149,8 +149,7 @@ private Task ConnectionTerminator()
{
while (!_cancellationTokenSource.IsCancellationRequested)
{
IPooledConnection conn = null;
if (_connections.Count > minimalConnCount && _connections.TryDequeue(out conn))
if (_connections.Count > minimalConnCount && _connections.TryDequeue(out var conn))
{
conn.Destroy();
Output.WriteLine($"Terminator killed a connection towards server {conn.Server}");
Expand All @@ -169,8 +168,7 @@ private async Task ConnectionTerminatorAsync()
const int minimalConnCount = 3;
while (!_cancellationTokenSource.IsCancellationRequested)
{
IPooledConnection conn = null;
if (_connections.Count > minimalConnCount && _connections.TryDequeue(out conn))
if (_connections.Count > minimalConnCount && _connections.TryDequeue(out var conn))
{
await conn.DestroyAsync();
Output.WriteLine($"Terminator killed connection {conn.Id} towards server {conn.Server}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ internal class ConnectionPoolMetrics : IConnectionPoolMetrics, IConnectionPoolLi
public long Acquired => _acquired;
public long TimedOutToAcquire => _timedOutToAcquire;


public string UniqueName { get; }

private IConnectionPool _pool;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@

namespace Neo4j.Driver.Internal.Metrics
{
internal class Metrics : IMetrics
internal class DefaultMetrics : IMetrics
{
private readonly ConcurrentDictionary<string, IConnectionPoolMetrics> _poolMetrics;
private readonly ConcurrentDictionary<string, IConnectionMetrics> _connMetrics;
private readonly Config _config;

public Metrics(Config config)
public DefaultMetrics(Config config)
{
_config = config;
_poolMetrics = new ConcurrentDictionary<string, IConnectionPoolMetrics>();
_connMetrics = new ConcurrentDictionary<string, IConnectionMetrics>();
}

public ConnectionPoolMetrics AddPoolMetrics(Uri poolUri, IConnectionPool pool)
public IConnectionPoolListener CreateConnectionPoolListener(Uri poolUri, IConnectionPool pool)
{
var acquisitionTimeout = _config.ConnectionAcquisitionTimeout;
var poolMetrics = new ConnectionPoolMetrics(poolUri, pool, acquisitionTimeout);
Expand All @@ -46,7 +46,7 @@ public ConnectionPoolMetrics AddPoolMetrics(Uri poolUri, IConnectionPool pool)
return poolMetrics;
}

public ConnectionMetrics AddConnMetrics(Uri poolUri)
public IConnectionListener CreateConnectionListener(Uri poolUri)
{
var connectionTimeout = _config.ConnectionTimeout;
var connMetrics = new ConnectionMetrics(poolUri, connectionTimeout);
Expand Down
29 changes: 29 additions & 0 deletions Neo4j.Driver/Neo4j.Driver.Metrics/DefaultMetricsFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2002-2018 "Neo Technology,"
// Network Engine for Objects in Lund AB [http://neotechnology.com]
//
// This file is part of Neo4j.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Neo4j.Driver.V1;

namespace Neo4j.Driver.Internal.Metrics
{
internal class DefaultMetricsFactory: IMetricsFactory
{
public IMetrics CreateMetrics(Config config)
{
return new DefaultMetrics(config);
}
}
}
26 changes: 26 additions & 0 deletions Neo4j.Driver/Neo4j.Driver.Metrics/Neo4j.Driver.Metrics.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net452;netstandard1.3</TargetFrameworks>
<AssemblyName>Neo4j.Driver.Metrics</AssemblyName>
<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute>
<AssemblyVersion>1.6.0.0</AssemblyVersion>
<GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
<AssemblyFileVersion>1.6.0.0</AssemblyFileVersion>
<GenerateAssemblyFileVersionAttribute>true</GenerateAssemblyFileVersionAttribute>
<Version>1.6.0</Version>
<RootNamespace>Neo4j.Driver.‌Internal.Metrics</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HdrHistogram" Version="2.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Neo4j.Driver\Neo4j.Driver.csproj" />
</ItemGroup>
</Project>
18 changes: 18 additions & 0 deletions Neo4j.Driver/Neo4j.Driver.Metrics/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Neo4j.Driver.Metrics")]
[assembly: AssemblyDescription("The internal metrics library to collect driver level metrics")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Neo4j.Driver")]
[assembly: AssemblyCopyright("Copyright © 2002-2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: InternalsVisibleTo("Neo4j.Driver.IntegrationTests")]
[assembly: InternalsVisibleTo("Neo4j.Driver.Tests")]
1 change: 1 addition & 0 deletions Neo4j.Driver/Neo4j.Driver.Tests/Neo4j.Driver.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<DotNetCliToolReference Include="dotnet-xunit" Version="$(XunitVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Neo4j.Driver.Metrics\Neo4j.Driver.Metrics.csproj" />
<ProjectReference Include="..\Neo4j.Driver\Neo4j.Driver.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp1.0'">
Expand Down
18 changes: 13 additions & 5 deletions Neo4j.Driver/Neo4j.Driver.sln
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26114.2
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo4j.Driver", "Neo4j.Driver\Neo4j.Driver.csproj", "{F5E54582-C024-4B99-AFEB-CA9638617BA0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo4j.Driver", "Neo4j.Driver\Neo4j.Driver.csproj", "{F5E54582-C024-4B99-AFEB-CA9638617BA0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo4j.Driver.Tests", "Neo4j.Driver.Tests\Neo4j.Driver.Tests.csproj", "{5642BD95-BF3C-4DFE-B5E5-1456EC9119BB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo4j.Driver.Tests", "Neo4j.Driver.Tests\Neo4j.Driver.Tests.csproj", "{5642BD95-BF3C-4DFE-B5E5-1456EC9119BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo4j.Driver.IntegrationTests", "Neo4j.Driver.IntegrationTests\Neo4j.Driver.IntegrationTests.csproj", "{02F68DF2-0047-4B04-93B6-521BD12B5D45}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo4j.Driver.IntegrationTests", "Neo4j.Driver.IntegrationTests\Neo4j.Driver.IntegrationTests.csproj", "{02F68DF2-0047-4B04-93B6-521BD12B5D45}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{622A94AD-BC4D-4162-AE43-A5CA055F24FC}"
ProjectSection(SolutionItems) = preProject
Expand All @@ -17,7 +16,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo4j.Driver.Tck.Tests", "Neo4j.Driver.Tck.Tests\Neo4j.Driver.Tck.Tests.csproj", "{E95B6563-4BC7-4B12-98C4-97FC8A8E5721}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Neo4j.Driver.Tck.Tests", "Neo4j.Driver.Tck.Tests\Neo4j.Driver.Tck.Tests.csproj", "{E95B6563-4BC7-4B12-98C4-97FC8A8E5721}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Neo4j.Driver.Metrics", "Neo4j.Driver.Metrics\Neo4j.Driver.Metrics.csproj", "{F5F689DC-352C-4C0C-8F07-466CF7FBF7B8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -41,8 +42,15 @@ Global
{E95B6563-4BC7-4B12-98C4-97FC8A8E5721}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E95B6563-4BC7-4B12-98C4-97FC8A8E5721}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E95B6563-4BC7-4B12-98C4-97FC8A8E5721}.Release|Any CPU.Build.0 = Release|Any CPU
{F5F689DC-352C-4C0C-8F07-466CF7FBF7B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F5F689DC-352C-4C0C-8F07-466CF7FBF7B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F5F689DC-352C-4C0C-8F07-466CF7FBF7B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F5F689DC-352C-4C0C-8F07-466CF7FBF7B8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2854D289-1659-47A6-957A-85612A6A2F5D}
EndGlobalSection
EndGlobal
28 changes: 7 additions & 21 deletions Neo4j.Driver/Neo4j.Driver/Internal/ConnectionPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ internal class ConnectionPool : LoggerBase, IConnectionPool
private readonly BlockingCollection<IPooledConnection> _idleConnections = new BlockingCollection<IPooledConnection>();
private readonly ConcurrentSet<IPooledConnection> _inUseConnections = new ConcurrentSet<IPooledConnection>();

private IDriverMetricsManager _metricsManager;
private IConnectionPoolListener _poolMetricsListener;
private readonly IConnectionPoolListener _poolMetricsListener;
private readonly IConnectionListener _connectionMetricsListener;

public int NumberOfInUseConnections => _inUseConnections.Count;
public int NumberOfIdleConnections => _idleConnections.Count;
Expand Down Expand Up @@ -94,7 +94,9 @@ public ConnectionPool(
var maxConnectionLifetime = connectionPoolSettings.MaxConnectionLifetime;
_connectionValidator = new ConnectionValidator(connIdleTimeout, maxConnectionLifetime);

SetupMetrics(connectionPoolSettings.Metrics);
var metrics = connectionPoolSettings.Metrics;
_poolMetricsListener = metrics?.CreateConnectionPoolListener(uri, this);
_connectionMetricsListener = metrics?.CreateConnectionListener(uri);
}

internal ConnectionPool(
Expand Down Expand Up @@ -170,7 +172,7 @@ private IPooledConnection NewPooledConnection()
{
if (TryIncrementPoolSize())
{
return _connectionFactory.Create(_uri, this, _metricsManager.ConnectionMetricsListener);
return _connectionFactory.Create(_uri, this, _connectionMetricsListener);
}
return null;
}
Expand Down Expand Up @@ -549,7 +551,6 @@ public void Close()
}

TerminateIdleConnections();
_metricsManager.Dispose();
});
}
}
Expand All @@ -570,7 +571,6 @@ public Task CloseAsync()
}

allCloseTasks.AddRange(TerminateIdleConnectionsAsync());
_metricsManager.Dispose();

return Task.WhenAll(allCloseTasks);
}
Expand Down Expand Up @@ -640,21 +640,7 @@ private static ConnectionPoolStatus AtomicRead(ref ConnectionPoolStatus value)
// a.k.a. do nothing but return the original value
return Interlocked.CompareExchange(ref value, Active, Active);
}

private void SetupMetrics(Metrics.Metrics metrics)
{
if ( metrics == null)
{
_metricsManager = new DevNullDriverMetricsManager();
}
else
{
_metricsManager = new DriverMetricsManager(metrics, _uri,
this);
}
_poolMetricsListener = _metricsManager.PoolMetricsListener;
}


public override string ToString()
{
return $"{nameof(_idleConnections)}: {{{_idleConnections.ToContentString()}}}, " +
Expand Down
6 changes: 3 additions & 3 deletions Neo4j.Driver/Neo4j.Driver/Internal/ConnectionPoolSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ internal class ConnectionPoolSettings
public TimeSpan ConnectionAcquisitionTimeout { get; }
public TimeSpan ConnectionIdleTimeout { get; }
public TimeSpan MaxConnectionLifetime { get; }
public Metrics.Metrics Metrics { get; }
public IMetrics Metrics { get; }

public ConnectionPoolSettings(Config config, Metrics.Metrics metrics = null)
public ConnectionPoolSettings(Config config, IMetrics metrics = null)
: this(config.MaxIdleConnectionPoolSize, config.MaxConnectionPoolSize, config.ConnectionAcquisitionTimeout,
config.ConnectionIdleTimeout, config.MaxConnectionLifetime, metrics)
{
}

internal ConnectionPoolSettings(int maxIdleConnectionPoolSize, int maxConnectionPoolSize,
TimeSpan connectionAcquisitionTimeout, TimeSpan connectionIdleTimeout, TimeSpan maxConnectionLifetime,
Metrics.Metrics metrics = null)
IMetrics metrics = null)
{
MaxIdleConnectionPoolSize = maxIdleConnectionPoolSize;
MaxConnectionPoolSize = maxConnectionPoolSize;
Expand Down
2 changes: 0 additions & 2 deletions Neo4j.Driver/Neo4j.Driver/Internal/Helpers/TemporalHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
// limitations under the License.

using System;
using HdrHistogram;
using HdrHistogram.Utilities;
using Neo4j.Driver.Internal.Protocol;
using Neo4j.Driver.Internal.Temporal;
using Neo4j.Driver.Internal.Types;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HdrHistogram;
using Neo4j.Driver.Internal.Messaging;
using Neo4j.Driver.V1;

Expand Down
Loading

0 comments on commit fd5d863

Please sign in to comment.