Skip to content

Commit

Permalink
Replaced TransactionCompletion delegates with interface implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
gliljas committed Jan 26, 2018
1 parent f0644cf commit 41342c3
Show file tree
Hide file tree
Showing 18 changed files with 393 additions and 106 deletions.
11 changes: 11 additions & 0 deletions src/AsyncGenerator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
- conversion: Ignore
name: Exists
containingTypeName: AbstractCollectionPersister
- conversion: ToAsync
rule: TransactionCompletion
- conversion: Ignore
name: QuoteTableAndColumns
containingTypeName: SchemaMetadataUpdater
Expand Down Expand Up @@ -135,6 +137,7 @@
requiresCancellationToken:
- rule: EventListener
- rule: ICache
- rule: TransactionCompletion
scanMethodBody: true
scanForMissingAsyncMembers:
- all: true
Expand Down Expand Up @@ -259,6 +262,14 @@ methodRules:
- containingType: NHibernate.Cache.ICache
name: Unlock
name: ICache
- filters:
- containingType: NHibernate.Action.IAfterTransactionCompletionProcess
name: Execute
- containingType: NHibernate.Action.IBeforeTransactionCompletionProcess
name: Execute
- containingType: NHibernate.Action.EntityAction
name: BeforeTransactionCompletionProcessImpl
name: TransactionCompletion
- filters:
- containingNamespace: NHibernate
- containingType: NHibernate.Tool.hbm2ddl.SchemaUpdate
Expand Down
50 changes: 50 additions & 0 deletions src/NHibernate/Action/AfterTransactionCompletionProcess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Threading;
using System.Threading.Tasks;

namespace NHibernate.Action
{
public partial class AfterTransactionCompletionProcess : IAfterTransactionCompletionProcess
{
private readonly Action<bool> _syncAction;
private readonly Func<bool, CancellationToken, Task> _asyncAction;

public AfterTransactionCompletionProcess(Action<bool> syncAction, Func<bool, CancellationToken, Task> asyncAction)
{

_syncAction = syncAction;
_asyncAction = asyncAction;
}

public AfterTransactionCompletionProcess(Action<bool> syncAction)
{
_syncAction = syncAction;
_asyncAction = (success, cancellationToken) =>
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled<object>(cancellationToken);
}
try
{
_syncAction(success);
return Task.CompletedTask;
}
catch (Exception ex)
{
return Task.FromException<object>(ex);
}
};
}

public void Execute(bool success)
{
_syncAction(success);
}

public Task ExecuteAsync(bool success, CancellationToken cancellationToken)
{
return _asyncAction(success, cancellationToken);
}
}
}
49 changes: 49 additions & 0 deletions src/NHibernate/Action/BeforeTransactionCompletionProcess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Threading;
using System.Threading.Tasks;

namespace NHibernate.Action
{
public class BeforeTransactionCompletionProcess : IBeforeTransactionCompletionProcess
{
private readonly System.Action _syncAction;
private readonly Func<CancellationToken, Task> _asyncAction;

public BeforeTransactionCompletionProcess(System.Action syncAction, Func<CancellationToken, Task> asyncAction)
{
_syncAction = syncAction;
_asyncAction = asyncAction;
}

public BeforeTransactionCompletionProcess(System.Action syncAction)
{
_syncAction = syncAction;
_asyncAction = (cancellationToken) =>
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled<object>(cancellationToken);
}
try
{
_syncAction();
return Task.CompletedTask;
}
catch (Exception ex)
{
return Task.FromException<object>(ex);
}
};
}

public void Execute()
{
_syncAction();
}

public Task ExecuteAsync(CancellationToken cancellationToken)
{
return _asyncAction(cancellationToken);
}
}
}
25 changes: 16 additions & 9 deletions src/NHibernate/Action/BulkOperationCleanupAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,23 +111,30 @@ public void Execute()
// nothing to do
}

public BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess
public IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess
{
get
{
get
{
return null;
}
}

public AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess
public IAfterTransactionCompletionProcess AfterTransactionCompletionProcess
{
get
{
return new AfterTransactionCompletionProcessDelegate((success) =>
{
this.EvictEntityRegions();
this.EvictCollectionRegions();
});
return new AfterTransactionCompletionProcess(
(success) =>
{
EvictEntityRegions();
EvictCollectionRegions();
},
async (success, cancellationToken) =>
{
await EvictEntityRegionsAsync(cancellationToken);
await EvictCollectionRegionsAsync(cancellationToken);
}
);
}
}

Expand Down
21 changes: 14 additions & 7 deletions src/NHibernate/Action/CollectionAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,27 +104,34 @@ public virtual void BeforeExecutions()
/// <summary>Execute this action</summary>
public abstract void Execute();

public virtual BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess
public virtual IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess
{
get
{
return null;
}
}

public virtual AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess
public virtual IAfterTransactionCompletionProcess AfterTransactionCompletionProcess
{

get
{
// Only make sense to add the delegate if there is a cache.
if (persister.HasCache)
{
return new AfterTransactionCompletionProcessDelegate((success) =>
{
CacheKey ck = new CacheKey(key, persister.KeyType, persister.Role, Session.Factory);
persister.Cache.Release(ck, softLock);
});
return new AfterTransactionCompletionProcess(
(success) =>
{
var ck = new CacheKey(key, persister.KeyType, persister.Role, Session.Factory);
persister.Cache.Release(ck, softLock);
},
async (success, cancellationToken) =>
{
var ck = new CacheKey(key, persister.KeyType, persister.Role, Session.Factory);
await persister.Cache.ReleaseAsync(ck, softLock, cancellationToken).ConfigureAwait(false);
}
);
}
return null;
}
Expand Down
68 changes: 43 additions & 25 deletions src/NHibernate/Action/CollectionUpdateAction.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using NHibernate.Cache;
using NHibernate.Cache.Access;
using NHibernate.Cache.Entry;
using NHibernate.Collection;
using NHibernate.Engine;
Expand Down Expand Up @@ -113,49 +114,66 @@ private void PostUpdate()
}
}

public override BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess
public override IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess
{
get
{
return null;
}
}

public override AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess
public override IAfterTransactionCompletionProcess AfterTransactionCompletionProcess
{
get
{
// Only make sense to add the delegate if there is a cache.
if (Persister.HasCache)
{
// NH Different behavior: to support unlocking collections from the cache.(r3260)
return new AfterTransactionCompletionProcessDelegate((success) =>
return new CollectionCacheUpdate(this);
}
return null;
}
}

private partial class CollectionCacheUpdate : IAfterTransactionCompletionProcess
{

private CollectionUpdateAction _action;

internal CollectionCacheUpdate(CollectionUpdateAction action)
{
_action = action;
}

public void Execute(bool success)
{
var session = _action.Session;
var persister = _action.Persister;
var cacheLock = _action.Lock;
CacheKey ck = session.GenerateCacheKey(_action.Key, persister.KeyType, persister.Role);

if (success)
{
var collection = _action.Collection;

// we can't disassemble a collection if it was uninitialized
// or detached from the session
if (collection.WasInitialized && session.PersistenceContext.ContainsCollection(collection))
{
CacheKey ck = Session.GenerateCacheKey(Key, Persister.KeyType, Persister.Role);
CollectionCacheEntry entry = new CollectionCacheEntry(collection, persister);
bool put = persister.Cache.AfterUpdate(ck, entry, null, cacheLock);

if (success)
if (put && session.Factory.Statistics.IsStatisticsEnabled)
{
// we can't disassemble a collection if it was uninitialized
// or detached from the session
if (Collection.WasInitialized && Session.PersistenceContext.ContainsCollection(Collection))
{
CollectionCacheEntry entry = new CollectionCacheEntry(Collection, Persister);
bool put = Persister.Cache.AfterUpdate(ck, entry, null, Lock);

if (put && Session.Factory.Statistics.IsStatisticsEnabled)
{
Session.Factory.StatisticsImplementor.SecondLevelCachePut(Persister.Cache.RegionName);
}
}
session.Factory.StatisticsImplementor.SecondLevelCachePut(persister.Cache.RegionName);
}
else
{
Persister.Cache.Release(ck, Lock);
}
});
}
}
else
{
persister.Cache.Release(ck, cacheLock);
}
return null;
}
}
}
}
}
8 changes: 4 additions & 4 deletions src/NHibernate/Action/EntityAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,22 @@ public void BeforeExecutions()

public abstract void Execute();

public virtual BeforeTransactionCompletionProcessDelegate BeforeTransactionCompletionProcess
public virtual IBeforeTransactionCompletionProcess BeforeTransactionCompletionProcess
{
get
{
return NeedsBeforeTransactionCompletion()
? new BeforeTransactionCompletionProcessDelegate(BeforeTransactionCompletionProcessImpl)
? new BeforeTransactionCompletionProcess(BeforeTransactionCompletionProcessImpl, BeforeTransactionCompletionProcessImplAsync)
: null;
}
}

public virtual AfterTransactionCompletionProcessDelegate AfterTransactionCompletionProcess
public virtual IAfterTransactionCompletionProcess AfterTransactionCompletionProcess
{
get
{
return NeedsAfterTransactionCompletion()
? new AfterTransactionCompletionProcessDelegate(AfterTransactionCompletionProcessImpl)
? new AfterTransactionCompletionProcess(AfterTransactionCompletionProcessImpl, AfterTransactionCompletionProcessImplAsync)
: null;
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/NHibernate/Action/IAfterTransactionCompletionProcess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace NHibernate.Action
{
public partial interface IAfterTransactionCompletionProcess
{
/// <summary>
/// Perform whatever processing is encapsulated here after completion of the transaction.
/// </summary>
/// <param name="success">Did the transaction complete successfully? True means it did.</param>
void Execute(bool success);
}
}
7 changes: 7 additions & 0 deletions src/NHibernate/Action/IBeforeTransactionCompletionProcess.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace NHibernate.Action
{
public partial interface IBeforeTransactionCompletionProcess
{
void Execute();
}
}
Loading

0 comments on commit 41342c3

Please sign in to comment.