Skip to content

Commit

Permalink
Merge pull request #12 from thedmi/feature/debug-logs
Browse files Browse the repository at this point in the history
feature: Add debug logs
  • Loading branch information
thedmi authored Feb 26, 2024
2 parents 24a7de8 + ea070e8 commit df0b097
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 20 deletions.
2 changes: 2 additions & 0 deletions sources/Capsule.Core/CapsuleHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ await Task.WhenAny(_taskChannel.Reader.WaitToReadAsync(stoppingToken).AsTask(),

// Shutting down, so await all tasks
await Task.WhenAll(_invocationLoopTasks).ConfigureAwait(false);

logger.LogDebug("Capsule host terminated");
}

private async Task SeparateCompletedTasksAsync()
Expand Down
4 changes: 2 additions & 2 deletions sources/Capsule.Core/DefaultInvocationLoopFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ namespace Capsule;

public class DefaultInvocationLoopFactory(ICapsuleLogger<ICapsuleInvocationLoop> logger) : ICapsuleInvocationLoopFactory
{
public ICapsuleInvocationLoop Create(ChannelReader<Func<Task>> reader)
public ICapsuleInvocationLoop Create(ChannelReader<Func<Task>> reader, Type capsuleType)
{
return new InvocationLoop(reader, logger);
return new InvocationLoop(reader, capsuleType, logger);
}
}
6 changes: 4 additions & 2 deletions sources/Capsule.Core/DefaultSynchronizerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ public class DefaultSynchronizerFactory(
{
public ICapsuleSynchronizer Create(object capsuleImpl, ICapsuleHost host)
{
var capsuleType = capsuleImpl.GetType();

var queue = queueFactory.CreateSynchronizerQueue();
var synchronizer = new CapsuleSynchronizer(queue.Writer, capsuleImpl.GetType());
var synchronizer = new CapsuleSynchronizer(queue.Writer, capsuleType);

ApplyFeatures(capsuleImpl, synchronizer);

host.Register(invocationLoopFactory.Create(queue.Reader));
host.Register(invocationLoopFactory.Create(queue.Reader, capsuleType));

return synchronizer;
}
Expand Down
2 changes: 1 addition & 1 deletion sources/Capsule.Core/ICapsuleInvocationLoopFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ namespace Capsule;

public interface ICapsuleInvocationLoopFactory
{
ICapsuleInvocationLoop Create(ChannelReader<Func<Task>> reader);
ICapsuleInvocationLoop Create(ChannelReader<Func<Task>> reader, Type capsuleType);
}
2 changes: 1 addition & 1 deletion sources/Capsule.Core/ICapsuleLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// ReSharper disable once UnusedTypeParameter
public interface ICapsuleLogger<T>
{
void LogDebug(string message);
void LogDebug(string message, params object?[] args);

void LogWarning(Exception exception, string message);

Expand Down
9 changes: 8 additions & 1 deletion sources/Capsule.Core/InvocationLoop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

namespace Capsule;

internal class InvocationLoop(ChannelReader<Func<Task>> reader, ICapsuleLogger<ICapsuleInvocationLoop> logger)
internal class InvocationLoop(
ChannelReader<Func<Task>> reader,
Type capsuleType,
ICapsuleLogger<ICapsuleInvocationLoop> logger)
: ICapsuleInvocationLoop
{
public async Task RunAsync(CancellationToken cancellationToken)
{
logger.LogDebug("Starting invocation loop for capsule {CapsuleType}...", capsuleType.FullName);

while (!cancellationToken.IsCancellationRequested)
{
try
Expand All @@ -33,6 +38,8 @@ public async Task RunAsync(CancellationToken cancellationToken)
await ExecuteAsync(f).ConfigureAwait(false);
}
}

logger.LogDebug("Invocation loop for capsule {CapsuleType} terminated", capsuleType.FullName);
}

private async Task ExecuteAsync(Func<Task> invocation)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace Capsule.Extensions.DependencyInjection;

/// <summary>
/// A hosted service that contains an <see cref="ICapsuleHost"/> and shuts it down when application shutdown is
/// initiated.
/// </summary>
public class CapsuleBackgroundService(CapsuleHost host) : BackgroundService
public class CapsuleBackgroundService(CapsuleHost host, ILogger<CapsuleBackgroundService> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
logger.LogDebug("Starting Capsule background service...");

await host.RunAsync(stoppingToken).ConfigureAwait(false);

logger.LogDebug("Capsule background service terminated");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace Capsule.Extensions.DependencyInjection;

public class LoggingAdapter<T>(ILogger<T> logger) : ICapsuleLogger<T>
{
public void LogDebug(string message)
public void LogDebug(string message, params object?[] args)
{
logger.LogDebug(message);
logger.LogDebug(message, args);
}

public void LogWarning(Exception exception, string message)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using Capsule.Extensions.DependencyInjection;

using Microsoft.Extensions.Logging;

using Moq;

using Shouldly;

namespace Capsule.Test.AutomatedTests.UnitTests;
Expand All @@ -21,7 +25,9 @@ public async Task Await_completion_returns_result_when_method_ran_to_completion_
private static async Task TestSuccessfulCompletion(Func<IAwaitCompletionTestSubject, Task<int>> testSubjectCall)
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down Expand Up @@ -65,7 +71,9 @@ public async Task Await_completion_throws_when_method_ran_to_completion_with_exc
private static async Task TestException(Func<IAwaitCompletionTestSubject, Task<int>> testSubjectCall)
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down Expand Up @@ -111,7 +119,9 @@ public async Task Await_completion_throws_when_method_is_cancelled_value_task()
private static async Task TestCancellation(Func<IAwaitCompletionTestSubject, Task<int>> testSubjectCall)
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using Capsule.Extensions.DependencyInjection;

using Microsoft.Extensions.Logging;

using Moq;

using Shouldly;

namespace Capsule.Test.AutomatedTests.UnitTests;
Expand All @@ -21,7 +25,9 @@ public async Task Await_enqueueing_returns_when_invocation_was_enqueued_value_ta
private static async Task TestSuccessful(Func<IAwaitEnqueueingTestSubject, Task> testSubjectCall)
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down Expand Up @@ -76,7 +82,9 @@ public async Task Await_enqueueing_does_not_throw_exception_when_capsule_method_
private static async Task TestException(Func<IAwaitEnqueueingTestSubject, Task> testSubjectCall)
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down Expand Up @@ -116,7 +124,9 @@ public async Task Await_enqueueing_does_not_throw_exception_when_capsule_method_
private static async Task TestCancellation(Func<IAwaitEnqueueingTestSubject, Task> testSubjectCall)
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using Capsule.Extensions.DependencyInjection;

using Microsoft.Extensions.Logging;

using Moq;

using Shouldly;

namespace Capsule.Test.AutomatedTests.UnitTests;
Expand All @@ -10,7 +14,9 @@ public class AwaitReceptionTest
public async Task Await_reception_returns_when_invocation_was_started()
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down Expand Up @@ -53,7 +59,9 @@ public async Task Await_reception_returns_when_invocation_was_started()
public async Task Await_reception_does_not_throw_exception_when_capsule_method_throws()
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down Expand Up @@ -82,7 +90,9 @@ public async Task Await_reception_does_not_throw_exception_when_capsule_method_t
public async Task Await_reception_does_not_throw_exception_when_capsule_method_is_cancelled()
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
using Capsule.Attribution;
using Capsule.Extensions.DependencyInjection;

using Microsoft.Extensions.Logging;

using Moq;

using Shouldly;

namespace Capsule.Test.AutomatedTests.UnitTests;
Expand All @@ -11,7 +15,9 @@ public class ConcurrencyTest
public async Task Capsule_does_not_produce_inconsistent_state_when_under_concurrent_load()
{
var runtimeContext = TestRuntime.Create();
var hostedService = new CapsuleBackgroundService((CapsuleHost)runtimeContext.Host);
var hostedService = new CapsuleBackgroundService(
(CapsuleHost)runtimeContext.Host,
Mock.Of<ILogger<CapsuleBackgroundService>>());

await hostedService.StartAsync(CancellationToken.None);

Expand Down

0 comments on commit df0b097

Please sign in to comment.