Skip to content

Commit

Permalink
WebServiceTarget - FlushAsync - Avoid premature flush (#1868)
Browse files Browse the repository at this point in the history
* WebServiceTarget - FlushAsync - Keeps track of pendingRequests to avoid premature flush

* WebServiceTarget - FlushAsync - Just keep track of pending request count

* Merge https://github.com/NLog/NLog into WebServiceTargetFlush

* WebServiceTarget - FlushAsync - Just keep track of pending request count (Test)
  • Loading branch information
snakefoot authored and 304NotModified committed Jan 11, 2017
1 parent b8f12a7 commit f46c1c6
Show file tree
Hide file tree
Showing 18 changed files with 355 additions and 57 deletions.
142 changes: 142 additions & 0 deletions src/NLog/Internal/AsyncOperationCounter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// Copyright (c) 2004-2016 Jaroslaw Kowalski <jaak@jkowalski.net>, Kim Christensen, Julian Verdurmen
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//

namespace NLog.Internal
{
using System;
using System.Collections.Generic;
using NLog.Common;

/// <summary>
/// Keeps track of pending operation count, and can notify when pending operation count reaches zero
/// </summary>
internal class AsyncOperationCounter
{
private int _pendingOperationCounter;
private readonly LinkedList<AsyncContinuation> _pendingCompletionList = new LinkedList<AsyncContinuation>();

/// <summary>
/// Mark operation has started
/// </summary>
public void BeginOperation()
{
System.Threading.Interlocked.Increment(ref _pendingOperationCounter);
}

/// <summary>
/// Mark operation has completed
/// </summary>
/// <param name="exception">Exception coming from the completed operation [optional]</param>
public void CompleteOperation(Exception exception)
{
if (_pendingCompletionList.Count > 0)
{
lock (_pendingCompletionList)
{
System.Threading.Interlocked.Decrement(ref _pendingOperationCounter);
var nodeNext = _pendingCompletionList.First;
while (nodeNext != null)
{
var nodeValue = nodeNext.Value;
nodeNext = nodeNext.Next;
nodeValue(exception); // Will modify _pendingCompletionList
}
}
}
else
{
System.Threading.Interlocked.Decrement(ref _pendingOperationCounter);
}
}

/// <summary>
/// Registers an AsyncContinuation to be called when all pending operations have completed
/// </summary>
/// <param name="asyncContinuation">Invoked on completion</param>
/// <returns>AsyncContinuation operation</returns>
public AsyncContinuation RegisterCompletionNotification(AsyncContinuation asyncContinuation)
{
if (_pendingOperationCounter == 0)
{
return asyncContinuation;
}
else
{
lock (_pendingCompletionList)
{
var pendingCompletion = new LinkedListNode<AsyncContinuation>(null);
_pendingCompletionList.AddLast(pendingCompletion);

// We only want to wait for the operations currently in progress (not the future operations)
int remainingCompletionCounter = System.Threading.Interlocked.Increment(ref _pendingOperationCounter);
if (remainingCompletionCounter <= 0)
{
System.Threading.Interlocked.Exchange(ref _pendingOperationCounter, 0);
_pendingCompletionList.Remove(pendingCompletion);
return asyncContinuation;
}

pendingCompletion.Value = (ex) =>
{
if (System.Threading.Interlocked.Decrement(ref remainingCompletionCounter) == 0)
{
lock (_pendingCompletionList)
{
System.Threading.Interlocked.Decrement(ref _pendingOperationCounter);
_pendingCompletionList.Remove(pendingCompletion);
var nodeNext = _pendingCompletionList.First;
while (nodeNext != null)
{
var nodeValue = nodeNext.Value;
nodeNext = nodeNext.Next;
nodeValue(ex); // Will modify _pendingCompletionList
}
}
asyncContinuation(ex);
}
};

return pendingCompletion.Value;
}
}
}

/// <summary>
/// Clear o
/// </summary>
public void Clear()
{
_pendingCompletionList.Clear();
}
}
}
1 change: 1 addition & 0 deletions src/NLog/NLog.Xamarin.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.Xamarin.iOS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.doc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.mono.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.netfx35.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.netfx40.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.netfx45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.sl4.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.sl5.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.wp7.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.wp71.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/NLog/NLog.wp8.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
<Compile Include="ILoggerBase-V1.cs" />
<Compile Include="ILogger-V1.cs" />
<Compile Include="Internal\ArrayHelper.cs" />
<Compile Include="Internal\AsyncOperationCounter.cs" />
<Compile Include="Internal\ConfigurationManager.cs" />
<Compile Include="Internal\DictionaryAdapter.cs" />
<Compile Include="Internal\EncodingHelpers.cs" />
Expand Down
Loading

0 comments on commit f46c1c6

Please sign in to comment.