From dffa8061c3d0b275c0363f4ccf6412ebb8304f07 Mon Sep 17 00:00:00 2001
From: Pavel Tikhomirov
Date: Tue, 8 Nov 2016 15:22:41 +0300
Subject: [PATCH 1/2] APNS Queue to ConcurrentQueue
---
PushSharp.Apple/ApnsConnection.cs | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/PushSharp.Apple/ApnsConnection.cs b/PushSharp.Apple/ApnsConnection.cs
index 0908b166..618eae01 100644
--- a/PushSharp.Apple/ApnsConnection.cs
+++ b/PushSharp.Apple/ApnsConnection.cs
@@ -5,6 +5,7 @@
using System.Threading.Tasks;
using System.Security.Cryptography.X509Certificates;
using System.Collections.Generic;
+using System.Collections.Concurrent;
using System.Threading;
using System.Net;
using PushSharp.Core;
@@ -68,22 +69,22 @@ public ApnsConnection (ApnsConfiguration configuration)
byte[] buffer = new byte[6];
int id;
-
SemaphoreSlim connectingSemaphore = new SemaphoreSlim (1);
SemaphoreSlim batchSendSemaphore = new SemaphoreSlim (1);
- object notificationBatchQueueLock = new object ();
+ object timerBatchWaitLock = new object ();
//readonly object connectingLock = new object ();
- Queue notifications = new Queue ();
+ ConcurrentQueue notifications = new ConcurrentQueue();
List sent = new List ();
Timer timerBatchWait;
public void Send (CompletableApnsNotification notification)
{
- lock (notificationBatchQueueLock) {
- notifications.Enqueue (notification);
+ notifications.Enqueue(notification);
+
+ lock (timerBatchWaitLock) {
if (notifications.Count >= Configuration.InternalBatchSize) {
@@ -113,15 +114,19 @@ async Task SendBatch ()
// Pause the timer
timerBatchWait.Change (Timeout.Infinite, Timeout.Infinite);
- if (notifications.Count <= 0)
+ if (notifications.IsEmpty)
return;
// Let's store the batch items to send internally
var toSend = new List ();
- while (notifications.Count > 0 && toSend.Count < Configuration.InternalBatchSize) {
- var n = notifications.Dequeue ();
- toSend.Add (n);
+ while (!notifications.IsEmpty && toSend.Count < Configuration.InternalBatchSize) {
+
+ CompletableApnsNotification n;
+ if (notifications.TryDequeue (out n))
+ {
+ toSend.Add(n);
+ }
}
From aeaecf7df2d4cfb4a867ba080e16abe611876b30 Mon Sep 17 00:00:00 2001
From: Pavel Tikhomirov
Date: Tue, 8 Nov 2016 16:44:20 +0300
Subject: [PATCH 2/2] APNS Queue to ConcurrentQueue: remove lock
---
PushSharp.Apple/ApnsConnection.cs | 35 +++++++++++++------------------
1 file changed, 15 insertions(+), 20 deletions(-)
diff --git a/PushSharp.Apple/ApnsConnection.cs b/PushSharp.Apple/ApnsConnection.cs
index 618eae01..a2bb7a8f 100644
--- a/PushSharp.Apple/ApnsConnection.cs
+++ b/PushSharp.Apple/ApnsConnection.cs
@@ -71,8 +71,7 @@ public ApnsConnection (ApnsConfiguration configuration)
SemaphoreSlim connectingSemaphore = new SemaphoreSlim (1);
SemaphoreSlim batchSendSemaphore = new SemaphoreSlim (1);
- object timerBatchWaitLock = new object ();
-
+
//readonly object connectingLock = new object ();
ConcurrentQueue notifications = new ConcurrentQueue();
List sent = new List ();
@@ -81,26 +80,22 @@ public ApnsConnection (ApnsConfiguration configuration)
public void Send (CompletableApnsNotification notification)
{
-
notifications.Enqueue(notification);
-
- lock (timerBatchWaitLock) {
-
- if (notifications.Count >= Configuration.InternalBatchSize) {
-
- // Make the timer fire immediately and send a batch off
- timerBatchWait.Change (0, Timeout.Infinite);
- return;
- }
-
- // Restart the timer to wait for more notifications to be batched
- // This timer will keep getting 'restarted' before firing as long as notifications
- // are queued before the timer's due time
- // if the timer is actually called, it means no more notifications were queued,
- // so we should flush out the queue instead of waiting for more to be batched as they
- // might not ever come and we don't want to leave anything stranded in the queue
- timerBatchWait.Change (Configuration.InternalBatchingWaitPeriod, Timeout.InfiniteTimeSpan);
+
+ if (notifications.Count >= Configuration.InternalBatchSize) {
+
+ // Make the timer fire immediately and send a batch off
+ timerBatchWait.Change (0, Timeout.Infinite);
+ return;
}
+
+ // Restart the timer to wait for more notifications to be batched
+ // This timer will keep getting 'restarted' before firing as long as notifications
+ // are queued before the timer's due time
+ // if the timer is actually called, it means no more notifications were queued,
+ // so we should flush out the queue instead of waiting for more to be batched as they
+ // might not ever come and we don't want to leave anything stranded in the queue
+ timerBatchWait.Change (Configuration.InternalBatchingWaitPeriod, Timeout.InfiniteTimeSpan);
}
long batchId = 0;