private Task <PersistentResponse> GetResponse(long messageId) { // Get all messages for the current set of signals return(GetMessages(messageId, Signals) .Then <List <Message>, long, PersistentResponse>((messages, id) => { if (!messages.Any()) { // No messages, not even commands return null; } // Get last message ID messageId = messages[messages.Count - 1].Id; // Do a single sweep through the results to process commands and extract values var messageValues = ProcessResults(messages); var response = new PersistentResponse { MessageId = messageId, Messages = messageValues, Disconnect = _disconnected }; PopulateResponseState(response); return response; }, messageId)); }
private Task <PersistentResponse> GetResponse(long messageId) { // Get all messages for the current set of signals return(GetMessages(messageId, Signals) .Success(messageTask => { var results = messageTask.Result; if (!results.Any()) { return WaitForSignal(messageId); } var response = new PersistentResponse(); var commands = results.Where(m => m.SignalKey.EndsWith(PersistentConnection.SignalrCommand)); ProcessCommands(commands); messageId = results.Max(p => p.Id); // Get the message values and the max message id we received var messageValues = results.Except(commands) .Select(m => m.Value) .ToList(); response.MessageId = messageId; response.Messages = messageValues; // Set the groups on the outgoing transport data response.TransportData["Groups"] = _groups; return TaskAsyncHelper.FromResult(response); }) .Unwrap()); }
private PersistentResponse GetResponse(MessageResult result) { // Do a single sweep through the results to process commands and extract values var messageValues = ProcessResults(result.Messages); var response = new PersistentResponse { MessageId = result.LastMessageId, Messages = messageValues, Disconnect = _disconnected, Aborted = _aborted, TimedOut = result.TimedOut }; PopulateResponseState(response); _trace.Source.TraceInformation("Connection: Connection '{0}' received {1} messages, last id {2}", _connectionId, result.Messages.Count, result.LastMessageId); Debug.WriteLine("Connection: Connection '{0}' received {1} messages, last id {2}", _connectionId, result.Messages.Count, result.LastMessageId); Debug.WriteLine("Connection: Messages"); Debug.WriteLine(_serializer.Stringify(result.Messages)); Debug.WriteLine("Connection: Response"); Debug.WriteLine(_serializer.Stringify(response)); return(response); }
private Task <PersistentResponse> GetResponse(long messageId) { // Get all messages for the current set of signals return(GetMessages(messageId, Signals) .Success(messageTask => { var results = messageTask.Result; if (!results.Any()) { return null; } var response = new PersistentResponse(); var commands = results.Where(m => m.SignalKey.EndsWith(PersistentConnection.SignalrCommand)); ProcessCommands(commands); messageId = results[results.Count - 1].Id; // Get the message values and the max message id we received var messageValues = results.Except(commands) .Select(m => m.Value) .ToList(); response.MessageId = messageId; response.Messages = messageValues; PopulateResponseState(response); return response; })); }
public Task <PersistentResponse> ReceiveAsync(string messageId, CancellationToken cancel, int maxMessages) { var tcs = new TaskCompletionSource <PersistentResponse>(); IDisposable subscription = null; const int stateUnassigned = 0; const int stateAssigned = 1; const int stateDisposed = 2; int state = stateUnassigned; CancellationTokenRegistration registration = cancel.Register(() => { // Dispose the subscription only if the handle has been assigned. If not, flag it so that the subscriber knows to Dispose of it for use if (Interlocked.Exchange(ref state, stateDisposed) == stateAssigned) { subscription.Dispose(); } }); PersistentResponse response = null; subscription = _bus.Subscribe(this, messageId, result => { if (Interlocked.CompareExchange(ref response, GetResponse(result), null) == null) { registration.Dispose(); // Dispose the subscription only if the handle has been assigned. If not, flag it so that the subscriber knows to Dispose of it for use if (Interlocked.Exchange(ref state, stateDisposed) == stateAssigned) { subscription.Dispose(); } } if (result.Terminal) { // Use the terminal message id since it's the most accurate // This is important for things like manipulating groups // since the message id is only updated after processing the commands // as part of this call itself. response.MessageId = result.LastMessageId; tcs.TrySetResult(response); return(TaskAsyncHelper.False); } return(TaskAsyncHelper.True); }, maxMessages); // If callbacks have already run, they maybe have not been able to Dispose the subscription because the instance was not yet assigned if (Interlocked.Exchange(ref state, stateAssigned) == stateDisposed) { // In this case, we will dispose of it immediately. subscription.Dispose(); } return(tcs.Task); }
private void PopulateResponseState(PersistentResponse response) { // Set the groups on the outgoing transport data if (_groups.Count > 0) { response.TransportData["Groups"] = _groups.GetSnapshot(); } }
private void PopulateResponseState(PersistentResponse response) { // Set the groups on the outgoing transport data if (_groups.Any()) { response.TransportData["Groups"] = _groups; } }
private void SerializePesistentResponse(PersistentResponse response, TextWriter writer) { var jsonWriter = new JsonTextWriter(writer); jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName("MessageId"); jsonWriter.WriteValue(response.MessageId); jsonWriter.WritePropertyName("Disconnect"); jsonWriter.WriteValue(response.Disconnect); jsonWriter.WritePropertyName("TimedOut"); jsonWriter.WriteValue(response.TimedOut); if (response.TransportData != null) { jsonWriter.WritePropertyName("TransportData"); jsonWriter.WriteStartObject(); object value; if (response.TransportData.TryGetValue("Groups", out value)) { jsonWriter.WritePropertyName("Groups"); jsonWriter.WriteStartArray(); foreach (var group in (IEnumerable <string>)value) { jsonWriter.WriteValue(group); } jsonWriter.WriteEndArray(); } jsonWriter.WriteEndObject(); } jsonWriter.WritePropertyName("Messages"); jsonWriter.WriteStartArray(); for (int i = 0; i < response.Messages.Count; i++) { ArraySegment <Message> segment = response.Messages[i]; for (int j = segment.Offset; j < segment.Offset + segment.Count; j++) { Message message = segment.Array[j]; if (!message.IsCommand) { jsonWriter.WriteRawValue(message.Value); } } } jsonWriter.WriteEndArray(); jsonWriter.WriteEndObject(); }
private PersistentResponse GetEmptyResponse(long?messageId) { var response = new PersistentResponse { MessageId = messageId ?? 0 }; PopulateResponseState(response); return(response); }
private PersistentResponse GetEmptyResponse(string messageId, bool timedOut = false) { var response = new PersistentResponse { MessageId = messageId, TimedOut = timedOut }; PopulateResponseState(response); return(response); }
private void PopulateResponseState(PersistentResponse response) { // Set the groups on the outgoing transport data if (_groups.Count > 0) { if (response.TransportData == null) { response.TransportData = new Dictionary <string, object>(); } response.TransportData["Groups"] = _groups.GetSnapshot(); } }
private Task <PersistentResponse> ProcessSignal(Task <SignalResult> signalTask, long?messageId = null) { if (signalTask.Result.TimedOut) { PersistentResponse response = GetEmptyResponse(messageId); // Return a task wrapping the result return(TaskAsyncHelper.FromResult(response)); } // Get the response for this message id return(GetResponse(messageId ?? 0).Success(task => task.Result ?? GetEmptyResponse(messageId))); }
private Task <PersistentResponse> ProcessSignal(SignalResult result, long?messageId = null) { if (result.TimedOut) { PersistentResponse response = GetEmptyResponse(messageId); // Return a task wrapping the result return(TaskAsyncHelper.FromResult(response)); } // Get the response for this message id return(GetResponse(messageId ?? 0) .Then <PersistentResponse, long?>((response, id) => response ?? GetEmptyResponse(id), messageId)); }
public Task <PersistentResponse> ReceiveAsync(string messageId, CancellationToken cancel, int maxMessages) { var tcs = new TaskCompletionSource <PersistentResponse>(); IDisposable subscription = null; var wh = new ManualResetEventSlim(initialState: false); CancellationTokenRegistration registration = cancel.Register(() => { wh.Wait(); subscription.Dispose(); }); PersistentResponse response = null; subscription = _bus.Subscribe(this, messageId, result => { wh.Wait(); if (Interlocked.CompareExchange(ref response, GetResponse(result), null) == null) { registration.Dispose(); subscription.Dispose(); } if (result.Terminal) { // Use the terminal message id since it's the most accurate // This is important for things like manipulating groups // since the message id is only updated after processing the commands // as part of this call itself. response.MessageId = result.LastMessageId; tcs.TrySetResult(response); return(TaskAsyncHelper.False); } return(TaskAsyncHelper.True); }, maxMessages); // Set this after the subscription is assigned wh.Set(); return(tcs.Task); }
private PersistentResponse GetResponse(MessageResult result) { // Do a single sweep through the results to process commands and extract values ProcessResults(result); var response = new PersistentResponse { MessageId = result.LastMessageId, Messages = result.Messages, Disconnect = _disconnected, Aborted = _aborted, TotalCount = result.TotalCount }; PopulateResponseState(response); return(response); }
private PersistentResponse GetResponse(MessageResult result) { // Do a single sweep through the results to process commands and extract values var messageValues = ProcessResults(result.Messages); var response = new PersistentResponse { MessageId = result.LastMessageId, Messages = messageValues, Disconnect = _disconnected, Aborted = _aborted }; PopulateResponseState(response); Trace.TraceInformation("Connection '{0}' received {1} messages, last id {2}", _connectionId, result.Messages.Count, result.LastMessageId); return(response); }
private PersistentResponse GetResponse(MessageResult result) { // Do a single sweep through the results to process commands and extract values ProcessResults(result); var response = new PersistentResponse(ExcludeMessage) { MessageId = result.LastMessageId, Messages = result.Messages, Disconnect = _disconnected, Aborted = _aborted, TotalCount = result.TotalCount, }; PopulateResponseState(response); _counters.ConnectionMessagesReceivedTotal.IncrementBy(result.TotalCount); _counters.ConnectionMessagesReceivedPerSec.IncrementBy(result.TotalCount); return(response); }
private Task <PersistentResponse> ProcessSignal(Task <SignalResult> signalTask, long?messageId = null) { if (signalTask.Result.TimedOut) { // If we timed out waiting for a signal we have a message id then return null PersistentResponse response = null; // Otherwise ee need to return 0 so that the next request we'll get all messages // on the next try if (messageId == null) { response = new PersistentResponse { MessageId = 0 }; } // Return a task wrapping the result return(TaskAsyncHelper.FromResult(response)); } // Get the response for this message id return(GetResponse(messageId ?? 0)); }
private PersistentResponse GetResponse(MessageResult result) { // Do a single sweep through the results to process commands and extract values ProcessResults(result); var response = new PersistentResponse { MessageId = result.LastMessageId, Messages = result.Messages, Disconnect = _disconnected, Aborted = _aborted, TotalCount = result.TotalCount }; PopulateResponseState(response); _counters.ConnectionMessagesReceivedTotal.IncrementBy(result.TotalCount); _counters.ConnectionMessagesReceivedPerSec.IncrementBy(result.TotalCount); return response; }
private void PopulateResponseState(PersistentResponse response) { // Set the groups on the outgoing transport data if (_groups.Count > 0) { if (response.TransportData == null) { response.TransportData = new Dictionary<string, object>(); } response.TransportData["Groups"] = _groups.GetSnapshot(); } }
private PersistentResponse GetResponse(MessageResult result) { // Do a single sweep through the results to process commands and extract values var messageValues = ProcessResults(result.Messages); var response = new PersistentResponse { MessageId = result.LastMessageId, Messages = messageValues, Disconnect = _disconnected, TimedOut = result.TimedOut }; PopulateResponseState(response); _trace.Source.TraceInformation("Connection: Connection {0} received {1} messages, last id {2}", _connectionId, result.Messages.Count, result.LastMessageId); Debug.WriteLine("Connection: Connection {0} received {1} messages, last id {2}. Payload {3}", _connectionId, result.Messages.Count, result.LastMessageId, _serializer.Stringify(result.Messages)); return response; }
private PersistentResponse GetResponse(MessageResult result) { // Do a single sweep through the results to process commands and extract values var messageValues = ProcessResults(result.Messages); var response = new PersistentResponse { MessageId = result.LastMessageId, Messages = messageValues, Disconnect = _disconnected, Aborted = _aborted }; PopulateResponseState(response); Trace.TraceInformation("Connection '{0}' received {1} messages, last id {2}", _connectionId, result.Messages.Count, result.LastMessageId); return response; }
private PersistentResponse GetResponse(MessageResult result) { // Do a single sweep through the results to process commands and extract values var messageValues = ProcessResults(result); var response = new PersistentResponse { MessageId = result.LastMessageId, Messages = messageValues, Disconnect = _disconnected, Aborted = _aborted }; PopulateResponseState(response); return response; }