1
0
mirror of synced 2024-11-25 04:03:09 +01:00

Bug fix in nested context disposing

This commit is contained in:
Menno van Lavieren 2017-07-10 14:14:54 +02:00
parent 8b5be4eef5
commit d386a3101e
2 changed files with 32 additions and 34 deletions

View File

@ -160,10 +160,10 @@ namespace Tapeti.Connection
public delegate Task Handler(MessageContext context, Func<Task> next); public delegate Task Handler(MessageContext context, Func<Task> next);
public class RecursiveCaller: ICallFrame public class RecursiveCaller
{ {
private Handler handle; private Handler handle;
private MessageContext context; private MessageContext currentContext;
private MessageContext nextContext; private MessageContext nextContext;
public RecursiveCaller next; public RecursiveCaller next;
@ -174,41 +174,55 @@ namespace Tapeti.Connection
internal async Task Call(MessageContext context) internal async Task Call(MessageContext context)
{ {
if (this.context != null) if (currentContext != null)
throw new InvalidOperationException("Cannot simultaneously call 'next' in Middleware."); throw new InvalidOperationException("Cannot simultaneously call 'next' in Middleware.");
try try
{ {
this.context = context; currentContext = context;
if (next != null) context.UseNestedContext = next == null ? (Action<MessageContext>)null : UseNestedContext;
context.SetCallFrame(this);
await handle(context, callNext); await handle(context, callNext);
} }
finally finally
{ {
context = null; currentContext = null;
} }
} }
private Task callNext() private async Task callNext()
{ {
if (next == null) if (next == null)
return Task.CompletedTask; return;
if (nextContext != null)
return next.Call(nextContext ?? context); {
await next.Call(nextContext);
}else
{
try
{
await next.Call(currentContext);
}
finally
{
currentContext.UseNestedContext = UseNestedContext;
}
}
} }
void ICallFrame.UseNestedContext(MessageContext context) void UseNestedContext(MessageContext context)
{ {
if (nextContext != null) if (nextContext != null)
throw new InvalidOperationException("Previous nested context was not yet disposed."); throw new InvalidOperationException("Previous nested context was not yet disposed.");
context.OnContextDisposed = OnContextDisposed;
nextContext = context; nextContext = context;
} }
void ICallFrame.OnContextDisposed(MessageContext context) void OnContextDisposed(MessageContext context)
{ {
context.OnContextDisposed = null;
if (nextContext == context) if (nextContext == context)
nextContext = null; nextContext = null;
} }

View File

@ -7,11 +7,6 @@ using System.Linq;
namespace Tapeti.Default namespace Tapeti.Default
{ {
public interface ICallFrame {
void UseNestedContext(MessageContext context);
void OnContextDisposed(MessageContext context);
}
public class MessageContext : IMessageContext public class MessageContext : IMessageContext
{ {
public IDependencyResolver DependencyResolver { get; set; } public IDependencyResolver DependencyResolver { get; set; }
@ -27,20 +22,14 @@ namespace Tapeti.Default
public IDictionary<string, object> Items { get; } public IDictionary<string, object> Items { get; }
private readonly MessageContext outerContext; private readonly MessageContext outerContext;
private ICallFrame callFrame; internal Action<MessageContext> UseNestedContext;
internal Action<MessageContext> OnContextDisposed;
public MessageContext() public MessageContext()
{ {
Items = new Dictionary<string, object>(); Items = new Dictionary<string, object>();
} }
public MessageContext(ICallFrame callFrame)
{
Items = new Dictionary<string, object>();
this.callFrame = callFrame;
}
private MessageContext(MessageContext outerContext) private MessageContext(MessageContext outerContext)
{ {
DependencyResolver = outerContext.DependencyResolver; DependencyResolver = outerContext.DependencyResolver;
@ -65,22 +54,17 @@ namespace Tapeti.Default
foreach (var value in items.Values) foreach (var value in items.Values)
(value as IDisposable)?.Dispose(); (value as IDisposable)?.Dispose();
callFrame?.OnContextDisposed(this); OnContextDisposed?.Invoke(this);
}
public void SetCallFrame(ICallFrame callFrame)
{
this.callFrame = callFrame;
} }
public IMessageContext SetupNestedContext() public IMessageContext SetupNestedContext()
{ {
if (callFrame == null) if (UseNestedContext == null)
throw new NotSupportedException("This context does not support creating nested contexts"); throw new NotSupportedException("This context does not support creating nested contexts");
var nested = new MessageContext(this); var nested = new MessageContext(this);
callFrame.UseNestedContext(nested); UseNestedContext(nested);
return nested; return nested;
} }