diff --git a/src/JustEat.StatsD/Buffered/StatsDUtf8Formatter.cs b/src/JustEat.StatsD/Buffered/StatsDUtf8Formatter.cs
index 66e48729..eee6a99d 100644
--- a/src/JustEat.StatsD/Buffered/StatsDUtf8Formatter.cs
+++ b/src/JustEat.StatsD/Buffered/StatsDUtf8Formatter.cs
@@ -4,7 +4,7 @@
namespace JustEat.StatsD.Buffered
{
- internal class StatsDUtf8Formatter
+ internal sealed class StatsDUtf8Formatter
{
private readonly byte[] _utf8Prefix;
diff --git a/src/JustEat.StatsD/DisposableTimer.cs b/src/JustEat.StatsD/DisposableTimer.cs
index b90040bc..0931bcb4 100644
--- a/src/JustEat.StatsD/DisposableTimer.cs
+++ b/src/JustEat.StatsD/DisposableTimer.cs
@@ -10,18 +10,18 @@ internal sealed class DisposableTimer : IDisposableTimer
private IStatsDPublisher _publisher;
private Stopwatch _stopwatch;
- public string StatName { get; set; }
+ public string Bucket { get; set; }
- public DisposableTimer(IStatsDPublisher publisher, string statName)
+ public DisposableTimer(IStatsDPublisher publisher, string bucket)
{
_publisher = publisher ?? throw new ArgumentNullException(nameof(publisher));
- if (string.IsNullOrEmpty(statName))
+ if (string.IsNullOrEmpty(bucket))
{
- throw new ArgumentNullException(nameof(statName));
+ throw new ArgumentNullException(nameof(bucket));
}
- StatName = statName;
+ Bucket = bucket;
_stopwatch = Stopwatch.StartNew();
}
@@ -32,12 +32,12 @@ public void Dispose()
_disposed = true;
_stopwatch.Stop();
- if (string.IsNullOrEmpty(StatName))
+ if (string.IsNullOrEmpty(Bucket))
{
- throw new InvalidOperationException($"The {nameof(StatName)} property must have a value.");
+ throw new InvalidOperationException($"The {nameof(Bucket)} property must have a value.");
}
- _publisher.Timing(_stopwatch.Elapsed, StatName);
+ _publisher.Timing(_stopwatch.Elapsed, Bucket);
_stopwatch = null;
_publisher = null;
diff --git a/src/JustEat.StatsD/EndpointLookups/CachedEndpointSource.cs b/src/JustEat.StatsD/EndpointLookups/CachedEndpointSource.cs
index a9d60386..8b8d59b1 100644
--- a/src/JustEat.StatsD/EndpointLookups/CachedEndpointSource.cs
+++ b/src/JustEat.StatsD/EndpointLookups/CachedEndpointSource.cs
@@ -22,9 +22,18 @@ public class CachedEndpointSource : IEndPointSource
///
/// is .
///
+ ///
+ /// is less than or equal to .
+ ///
public CachedEndpointSource(IEndPointSource inner, TimeSpan cacheDuration)
{
_inner = inner ?? throw new ArgumentNullException(nameof(inner));
+
+ if (cacheDuration <= TimeSpan.Zero)
+ {
+ throw new ArgumentOutOfRangeException(nameof(cacheDuration), cacheDuration, "The end point cache duration must be a positive TimeSpan value.");
+ }
+
_cachedValue = null;
_cacheDuration = cacheDuration;
}
diff --git a/src/JustEat.StatsD/EndpointLookups/DnsLookupIpEndpointSource.cs b/src/JustEat.StatsD/EndpointLookups/DnsLookupIpEndpointSource.cs
index b6e6053d..a820844e 100644
--- a/src/JustEat.StatsD/EndpointLookups/DnsLookupIpEndpointSource.cs
+++ b/src/JustEat.StatsD/EndpointLookups/DnsLookupIpEndpointSource.cs
@@ -7,7 +7,7 @@ namespace JustEat.StatsD.EndpointLookups
{
///
/// A class representing an implementation of that looks up
- /// the for DNS hostname to resolve its IP address.
+ /// the for a DNS hostname to resolve its IP address.
///
public class DnsLookupIpEndpointSource : IEndPointSource
{
diff --git a/src/JustEat.StatsD/IDisposableTimer.cs b/src/JustEat.StatsD/IDisposableTimer.cs
index 325ce90f..9f60575e 100644
--- a/src/JustEat.StatsD/IDisposableTimer.cs
+++ b/src/JustEat.StatsD/IDisposableTimer.cs
@@ -8,8 +8,8 @@ namespace JustEat.StatsD
public interface IDisposableTimer : IDisposable
{
///
- /// Gets or sets the name of the StatsD bucket associated with the timer.
+ /// Gets or sets the StatsD bucket associated with the timer.
///
- string StatName { get; set; }
+ string Bucket { get; set; }
}
}
diff --git a/src/JustEat.StatsD/SocketProtocol.cs b/src/JustEat.StatsD/SocketProtocol.cs
index e0327336..8694d958 100644
--- a/src/JustEat.StatsD/SocketProtocol.cs
+++ b/src/JustEat.StatsD/SocketProtocol.cs
@@ -1,9 +1,11 @@
+using System.Net.Sockets;
+
namespace JustEat.StatsD
{
///
- /// The subset of ProtocolType that are supported by SocketTransport
- /// UDP or IP.
- /// UDP is the default, but IP transport is required for AWS Lambdas.
+ /// An enumeration defining the subset of values that are supported by .
+ ///
+ /// UDP is the default, but IP transport is required for some environments such as AWS Lambda functions.
///
public enum SocketProtocol
{
diff --git a/src/JustEat.StatsD/TimerExtensions.cs b/src/JustEat.StatsD/TimerExtensions.cs
index ddab4d90..06315e07 100644
--- a/src/JustEat.StatsD/TimerExtensions.cs
+++ b/src/JustEat.StatsD/TimerExtensions.cs
@@ -18,6 +18,9 @@ public static class TimerExtensions
///
/// An that publishes the metric when the instance is disposed of.
///
+ ///
+ /// or is .
+ ///
public static IDisposableTimer StartTimer(this IStatsDPublisher publisher, string bucket)
{
return new DisposableTimer(publisher, bucket);
@@ -30,8 +33,16 @@ public static IDisposableTimer StartTimer(this IStatsDPublisher publisher, strin
/// The to publish with.
/// The bucket to publish the timer for.
/// A delegate to a method whose invocation should be timed.
+ ///
+ /// , or is .
+ ///
public static void Time(this IStatsDPublisher publisher, string bucket, Action action)
{
+ if (action == null)
+ {
+ throw new ArgumentNullException(nameof(action));
+ }
+
using (StartTimer(publisher, bucket))
{
action();
@@ -45,8 +56,16 @@ public static void Time(this IStatsDPublisher publisher, string bucket, Action a
/// The to publish with.
/// The bucket to publish the timer for.
/// A delegate to a method whose invocation should be timed.
+ ///
+ /// , or is .
+ ///
public static void Time(this IStatsDPublisher publisher, string bucket, Action action)
{
+ if (action == null)
+ {
+ throw new ArgumentNullException(nameof(action));
+ }
+
using (var timer = StartTimer(publisher, bucket))
{
action(timer);
@@ -63,8 +82,16 @@ public static void Time(this IStatsDPublisher publisher, string bucket, Action
/// A representing the asynchronous operation to time.
///
+ ///
+ /// , or is .
+ ///
public static async Task Time(this IStatsDPublisher publisher, string bucket, Func action)
{
+ if (action == null)
+ {
+ throw new ArgumentNullException(nameof(action));
+ }
+
using (StartTimer(publisher, bucket))
{
await action().ConfigureAwait(false);
@@ -82,8 +109,16 @@ public static async Task Time(this IStatsDPublisher publisher, string bucket, Fu
///
/// A representing the asynchronous operation to time.
///
+ ///
+ /// , or is .
+ ///
public static async Task Time(this IStatsDPublisher publisher, string bucket, Func action)
{
+ if (action == null)
+ {
+ throw new ArgumentNullException(nameof(action));
+ }
+
using (var timer = StartTimer(publisher, bucket))
{
await action(timer).ConfigureAwait(false);
@@ -101,8 +136,16 @@ public static async Task Time(this IStatsDPublisher publisher, string bucket, Fu
///
/// The value from invoking .
///
+ ///
+ /// , or is .
+ ///
public static T Time(this IStatsDPublisher publisher, string bucket, Func func)
{
+ if (func == null)
+ {
+ throw new ArgumentNullException(nameof(func));
+ }
+
using (StartTimer(publisher, bucket))
{
return func();
@@ -120,8 +163,16 @@ public static T Time(this IStatsDPublisher publisher, string bucket, Func
///
/// The value from invoking .
///
+ ///
+ /// , or is .
+ ///
public static T Time(this IStatsDPublisher publisher, string bucket, Func func)
{
+ if (func == null)
+ {
+ throw new ArgumentNullException(nameof(func));
+ }
+
using (var timer = StartTimer(publisher, bucket))
{
return func(timer);
@@ -139,8 +190,16 @@ public static T Time(this IStatsDPublisher publisher, string bucket, Func
/// A representing the asynchronous operation to time.
///
+ ///
+ /// , or is .
+ ///
public static async Task Time(this IStatsDPublisher publisher, string bucket, Func> func)
{
+ if (func == null)
+ {
+ throw new ArgumentNullException(nameof(func));
+ }
+
using (StartTimer(publisher, bucket))
{
return await func().ConfigureAwait(false);
@@ -158,8 +217,16 @@ public static async Task Time(this IStatsDPublisher publisher, string buck
///
/// A representing the asynchronous operation to time.
///
+ ///
+ /// , or is .
+ ///
public static async Task Time(this IStatsDPublisher publisher, string bucket, Func> func)
{
+ if (func == null)
+ {
+ throw new ArgumentNullException(nameof(func));
+ }
+
using (var timer = StartTimer(publisher, bucket))
{
return await func(timer).ConfigureAwait(false);
diff --git a/tests/JustEat.StatsD.Tests/EndpointLookups/CachedEndpointSourceTests.cs b/tests/JustEat.StatsD.Tests/EndpointLookups/CachedEndpointSourceTests.cs
index b8cbe94d..c94529fa 100644
--- a/tests/JustEat.StatsD.Tests/EndpointLookups/CachedEndpointSourceTests.cs
+++ b/tests/JustEat.StatsD.Tests/EndpointLookups/CachedEndpointSourceTests.cs
@@ -62,6 +62,21 @@ public static async Task CachedValueIsReturnedAgainAfterExpiry()
mockInner.Verify(x => x.GetEndpoint(), Times.Exactly(2));
}
+ [Theory]
+ [InlineData(0)]
+ [InlineData(-1)]
+ public static void ConstructorThrowsIfCacheDurationIsInvalid(long ticks)
+ {
+ // Arrange
+ var inner = Mock.Of();
+ var cacheDuration = TimeSpan.FromTicks(ticks);
+
+ // Act and Assert
+ var exception = Assert.Throws("cacheDuration", () => new CachedEndpointSource(inner, cacheDuration));
+
+ exception.ActualValue.ShouldBe(cacheDuration);
+ }
+
private static IPEndPoint MakeTestIpEndPoint()
{
return new IPEndPoint(new IPAddress(new byte[] { 1, 2, 3, 4 }), 8125);
diff --git a/tests/JustEat.StatsD.Tests/Extensions/ExtensionsTests.cs b/tests/JustEat.StatsD.Tests/Extensions/ExtensionsTests.cs
index b052fbdf..230734ed 100644
--- a/tests/JustEat.StatsD.Tests/Extensions/ExtensionsTests.cs
+++ b/tests/JustEat.StatsD.Tests/Extensions/ExtensionsTests.cs
@@ -29,7 +29,7 @@ public static void CanChangeStatName()
using (var timer = publisher.StartTimer("defaultName"))
{
Delay();
- timer.StatName = "otherStat";
+ timer.Bucket = "otherStat";
}
PublisherAssertions.SingleStatNameIs(publisher, "otherStat");
@@ -120,7 +120,7 @@ public static void CanChangeStatNameInAction()
publisher.Time("defaultName", t =>
{
Delay();
- t.StatName = "otherStat";
+ t.Bucket = "otherStat";
});
PublisherAssertions.SingleStatNameIs(publisher, "otherStat");
@@ -182,7 +182,7 @@ public static async Task CanChangeStatNameInAsyncFunction()
await publisher.Time("defaultName", async t =>
{
var result = await DelayedAnswerAsync();
- t.StatName = "afterTheAwait";
+ t.Bucket = "afterTheAwait";
return result;
});
diff --git a/tests/JustEat.StatsD.Tests/Extensions/SimpleTimerStatNameTests.cs b/tests/JustEat.StatsD.Tests/Extensions/SimpleTimerStatNameTests.cs
index b771c06a..22c60266 100644
--- a/tests/JustEat.StatsD.Tests/Extensions/SimpleTimerStatNameTests.cs
+++ b/tests/JustEat.StatsD.Tests/Extensions/SimpleTimerStatNameTests.cs
@@ -28,7 +28,7 @@ public static void CanChangeStatNameDuringOperation()
using (var timer = publisher.StartTimer("initialStat"))
{
Delay();
- timer.StatName = "changedValue";
+ timer.Bucket = "changedValue";
}
PublisherAssertions.SingleStatNameIs(publisher, "changedValue");
@@ -42,7 +42,7 @@ public static void StatNameCanBeAppended()
using (var timer = publisher.StartTimer("Some."))
{
Delay();
- timer.StatName += "More";
+ timer.Bucket += "More";
}
PublisherAssertions.SingleStatNameIs(publisher, "Some.More");
@@ -69,7 +69,7 @@ public static void StatWithoutNameAtEndThrows()
using (var timer = publisher.StartTimer("valid.Stat"))
{
Delay();
- timer.StatName = null;
+ timer.Bucket = null;
}
});
@@ -88,7 +88,7 @@ public static void StatNameIsInitialValueWhenExceptionIsThrown()
using (var timer = publisher.StartTimer("initialStat"))
{
Fail();
- timer.StatName = "changedValue";
+ timer.Bucket = "changedValue";
}
}
catch (Exception)