mirror of
https://github.com/Readarr/Readarr.git
synced 2026-04-17 21:25:39 -04:00
Upgraded SignalR to 1.2.2
This commit is contained in:
@@ -33,8 +33,10 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
_escapedKey = minifiedKey;
|
||||
}
|
||||
|
||||
public static void WriteCursors(TextWriter textWriter, IList<Cursor> cursors)
|
||||
public static void WriteCursors(TextWriter textWriter, IList<Cursor> cursors, string prefix)
|
||||
{
|
||||
textWriter.Write(prefix);
|
||||
|
||||
for (int i = 0; i < cursors.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
@@ -48,7 +50,7 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteUlongAsHexToBuffer(ulong value, TextWriter textWriter)
|
||||
internal static void WriteUlongAsHexToBuffer(ulong value, TextWriter textWriter)
|
||||
{
|
||||
// This tracks the length of the output and serves as the index for the next character to be written into the pBuffer.
|
||||
// The length could reach up to 16 characters, so at least that much space should remain in the pBuffer.
|
||||
@@ -114,17 +116,17 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static List<Cursor> GetCursors(string cursor)
|
||||
public static List<Cursor> GetCursors(string cursor, string prefix)
|
||||
{
|
||||
return GetCursors(cursor, s => s);
|
||||
return GetCursors(cursor, prefix, s => s);
|
||||
}
|
||||
|
||||
public static List<Cursor> GetCursors(string cursor, Func<string, string> keyMaximizer)
|
||||
public static List<Cursor> GetCursors(string cursor, string prefix, Func<string, string> keyMaximizer)
|
||||
{
|
||||
return GetCursors(cursor, (key, state) => ((Func<string, string>)state).Invoke(key), keyMaximizer);
|
||||
return GetCursors(cursor, prefix, (key, state) => ((Func<string, string>)state).Invoke(key), keyMaximizer);
|
||||
}
|
||||
|
||||
public static List<Cursor> GetCursors(string cursor, Func<string, object, string> keyMaximizer, object state)
|
||||
public static List<Cursor> GetCursors(string cursor, string prefix, Func<string, object, string> keyMaximizer, object state)
|
||||
{
|
||||
// Technically GetCursors should never be called with a null value, so this is extra cautious
|
||||
if (String.IsNullOrEmpty(cursor))
|
||||
@@ -132,6 +134,14 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
throw new FormatException(Resources.Error_InvalidCursorFormat);
|
||||
}
|
||||
|
||||
// If the cursor does not begin with the prefix stream, it isn't necessarily a formatting problem.
|
||||
// The cursor with a different prefix might have had different, but also valid, formatting.
|
||||
// Null should be returned so new cursors will be generated
|
||||
if (!cursor.StartsWith(prefix, StringComparison.Ordinal))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var signals = new HashSet<string>();
|
||||
var cursors = new List<Cursor>();
|
||||
string currentKey = null;
|
||||
@@ -143,8 +153,10 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
var sbEscaped = new StringBuilder();
|
||||
Cursor parsedCursor;
|
||||
|
||||
foreach (var ch in cursor)
|
||||
for (int i = prefix.Length; i < cursor.Length; i++)
|
||||
{
|
||||
var ch = cursor[i];
|
||||
|
||||
// escape can only be true if we are consuming the key
|
||||
if (escape)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.SignalR.Infrastructure;
|
||||
|
||||
@@ -11,6 +13,8 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
{
|
||||
internal class DefaultSubscription : Subscription
|
||||
{
|
||||
internal static string _defaultCursorPrefix = GetCursorPrefix();
|
||||
|
||||
private List<Cursor> _cursors;
|
||||
private List<Topic> _cursorTopics;
|
||||
|
||||
@@ -36,7 +40,7 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
else
|
||||
{
|
||||
// Ensure delegate continues to use the C# Compiler static delegate caching optimization.
|
||||
_cursors = Cursor.GetCursors(cursor, (k, s) => UnminifyCursor(k, s), stringMinifier) ?? GetCursorsFromEventKeys(EventKeys, topics);
|
||||
_cursors = Cursor.GetCursors(cursor, _defaultCursorPrefix, (k, s) => UnminifyCursor(k, s), stringMinifier) ?? GetCursorsFromEventKeys(EventKeys, topics);
|
||||
}
|
||||
|
||||
_cursorTopics = new List<Topic>();
|
||||
@@ -126,7 +130,7 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
{
|
||||
lock (_cursors)
|
||||
{
|
||||
Cursor.WriteCursors(textWriter, _cursors);
|
||||
Cursor.WriteCursors(textWriter, _cursors, _defaultCursorPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +200,22 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
return list;
|
||||
}
|
||||
|
||||
private static string GetCursorPrefix()
|
||||
{
|
||||
using (var rng = new RNGCryptoServiceProvider())
|
||||
{
|
||||
var data = new byte[4];
|
||||
rng.GetBytes(data);
|
||||
|
||||
using (var writer = new StringWriter(CultureInfo.InvariantCulture))
|
||||
{
|
||||
var randomValue = (ulong)BitConverter.ToUInt32(data, 0);
|
||||
Cursor.WriteUlongAsHexToBuffer(randomValue, writer);
|
||||
return "d-" + writer.ToString() + "-";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong GetMessageId(TopicLookup topics, string key)
|
||||
{
|
||||
Topic topic;
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!subscription.UnsetQueued() || workTask.IsFaulted)
|
||||
if (!subscription.UnsetQueued() || workTask.IsFaulted || workTask.IsCanceled)
|
||||
{
|
||||
// If we don't have more work to do just make the subscription null
|
||||
subscription = null;
|
||||
@@ -271,7 +271,7 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
Trace.TraceEvent(TraceEventType.Error, 0, "Work failed for " + subscription.Identity + ": " + task.Exception.GetBaseException());
|
||||
}
|
||||
|
||||
if (moreWork && !task.IsFaulted)
|
||||
if (moreWork && !task.IsFaulted && !task.IsCanceled)
|
||||
{
|
||||
PumpImpl(taskCompletionSource, subscription);
|
||||
}
|
||||
@@ -295,10 +295,7 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
|
||||
Trace.TraceEvent(TraceEventType.Verbose, 0, "Dispoing the broker");
|
||||
|
||||
//Check if OS is not Windows and exit
|
||||
var platform = (int)Environment.OSVersion.Platform;
|
||||
|
||||
if ((platform == 4) || (platform == 6) || (platform == 128))
|
||||
if (MonoUtility.IsRunningMono)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
private static readonly List<ArraySegment<Message>> _emptyList = new List<ArraySegment<Message>>();
|
||||
public readonly static MessageResult TerminalMessage = new MessageResult(terminal: true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="T:IList{Message}"/> associated with the result.
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an optimization to avoid allocations.")]
|
||||
public IList<ArraySegment<Message>> Messages { get; private set; }
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
{
|
||||
public class ScaleoutSubscription : Subscription
|
||||
{
|
||||
private const string _scaleoutCursorPrefix = "s-";
|
||||
|
||||
private readonly IList<ScaleoutMappingStore> _streams;
|
||||
private readonly List<Cursor> _cursors;
|
||||
|
||||
@@ -40,10 +42,15 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
}
|
||||
else
|
||||
{
|
||||
cursors = Cursor.GetCursors(cursor);
|
||||
cursors = Cursor.GetCursors(cursor, _scaleoutCursorPrefix);
|
||||
|
||||
// If the cursor had a default prefix, "d-", cursors might be null
|
||||
if (cursors == null)
|
||||
{
|
||||
cursors = new List<Cursor>();
|
||||
}
|
||||
// If the streams don't match the cursors then throw it out
|
||||
if (cursors.Count != _streams.Count)
|
||||
else if (cursors.Count != _streams.Count)
|
||||
{
|
||||
cursors.Clear();
|
||||
}
|
||||
@@ -63,7 +70,7 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
|
||||
public override void WriteCursor(TextWriter textWriter)
|
||||
{
|
||||
Cursor.WriteCursors(textWriter, _cursors);
|
||||
Cursor.WriteCursors(textWriter, _cursors, _scaleoutCursorPrefix);
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists", Justification = "The list needs to be populated")]
|
||||
|
||||
@@ -120,13 +120,7 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
|
||||
WorkImpl(tcs);
|
||||
|
||||
// Fast Path
|
||||
if (tcs.Task.IsCompleted)
|
||||
{
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
return FinishAsync(tcs);
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
public bool SetQueued()
|
||||
@@ -140,19 +134,6 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
return Interlocked.CompareExchange(ref _state, State.Idle, State.Working) != State.Working;
|
||||
}
|
||||
|
||||
private static Task FinishAsync(TaskCompletionSource<object> tcs)
|
||||
{
|
||||
return tcs.Task.ContinueWith(task =>
|
||||
{
|
||||
if (task.IsFaulted)
|
||||
{
|
||||
return TaskAsyncHelper.FromError(task.Exception);
|
||||
}
|
||||
|
||||
return TaskAsyncHelper.Empty;
|
||||
}).FastUnwrap();
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "We have a sync and async code path.")]
|
||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We want to avoid user code taking the process down.")]
|
||||
private void WorkImpl(TaskCompletionSource<object> taskCompletionSource)
|
||||
@@ -200,7 +181,14 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
taskCompletionSource.TrySetUnwrappedException(ex);
|
||||
if (ex.InnerException is TaskCanceledException)
|
||||
{
|
||||
taskCompletionSource.TrySetCanceled();
|
||||
}
|
||||
else
|
||||
{
|
||||
taskCompletionSource.TrySetUnwrappedException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -233,6 +221,10 @@ namespace Microsoft.AspNet.SignalR.Messaging
|
||||
{
|
||||
taskCompletionSource.TrySetUnwrappedException(task.Exception);
|
||||
}
|
||||
else if (task.IsCanceled)
|
||||
{
|
||||
taskCompletionSource.TrySetCanceled();
|
||||
}
|
||||
else if (task.Result)
|
||||
{
|
||||
WorkImpl(taskCompletionSource);
|
||||
|
||||
Reference in New Issue
Block a user