Are SignalR Client function calls waiting for I/O or not? - signalr

In my .NET code on the server, I call a my SignalR client functions similar to this:
GlobalHost.ConnectionManager.GetHubContext("MyHub").Clients.
All.TotalActive_Chart(TimeStamp,
Name,
Total,
Active)
Does this call return before all the I/O is complete or does it wait until all the clients have been sent the data? With 100 clients connected, would it help if I thread this off?

Related

Synchronous and Asynchronous Communication

In Synchronous, the server sends a message to a client and waits for a response. The program is blocked until a response message is returned to server.
In Asynchronous, the server sends a message to a client and waits for a response. While waiting, the server program is not blocking and can continue to execute. However, when a response is returned back to server, server will receive and sends message again.
My question here is synchronous communication can only have one server communicate with one client? However, asynchronous communication allows one server to communicate with multiple clients?
I am read a few articles and try to understand but I am still confused with synchronous and asynchronous communication. Hope anyone can help me, thanks in advance.

RabbitMQ synchronous messaging pros and cons

as we all know message bus like rabbitMQ is mainly meant for asynchronous messaging so standard approch is to fire and forget like publish something on bus and don't worry about who will process published message or when. But i'm thinking about latest talk in our development team about synchronous processing of message: case would be to publish message to service bus and as as publisher i want to wait for any subscriber to process message and return results to me - so it looks rather as request-response model. I'm thinking now of one con like degrading performance in this model. What are your thoughts? When to use async and when sync? What are the tradeoffs?
Synchronous messaging is possible but impacts scalability. If a publisher has to wait for its recipients to respond, then it will be limited in how much it can achieve at any given time.
However, you can achieve request-response using asynchronous messaging. In RabbitMQ, you do this by means of the Remote Procedure Call (RPC) pattern.
To put it simply, your publisher publishes a message, but doesn't wait for the response; it can continue doing other stuff in the meantime. The publisher does keep track of it though, by putting a CorrelationId on the message, and storing it locally. The message eventually reaches a consumer, who processes it and responds back to the publisher on a different queue. The reply has the same CorrelationId. When the publisher receives the reply, it can then mark that particular call (via the CorrelationId) as processed.
If you want, you can also do other things with the CorrelatonId, such as timeout those messages for which we haven't received a reply after e.g. 30 seconds.

SignalR queue limit per user

I have this code to test asynchronous programming in SignalR. this code send back to client the text after 10 seconds.
public class TestHub : Hub
{
public async Task BroadcastMessage(string text)
{
await DelayResponse(text);
}
async Task DelayResponse(string text)
{
await Task.Delay(10000);
Clients.All.displayText(text);
}
}
this code work fine but there is an unexpected behavior. when 5 messages are sent in less than 10 second, client can't send more message until previous "DelayResponse" methods end. it happens per connection and if before 10 seconds close the connection and reopen it, client can send 5 messages again. I test it with chrome, firefox and IE.
I made some mistake or it is signalr limitation?
You are most likely hitting a browser limit. When using longPolling and serverSentEvent transport each send is a separate HTTP request. Since you are delaying response these requests are longer running and browsers have limits of how many concurrent connection can be opened. Once you reach the limit a new connection will not be open until one of the previous ones is completed.
More details on concurrent requests limit:
Max parallel http connections in a browser?
That's not the sens of signalR, that you waiting for a "long running" task. For that signalR supports server push mechanisme.
So if you have something which needs more time you can trigger this from client.
In the case the calculation is finish you can send a message from server to client.

Does SignalR provide message integrity mechanisms which ensure that no messages are lost during client reconnect

Abstract
Hi, I was pondering whether it is possible to loose a message with SignalR. Suppose client disconnects but eventually reconnects in a short amount of time, for example 3 seconds. Will the client get all of the messages that were sent to him while he was disconnected?
For example let's consider LongPolling transport. As far as I'm aware long polling is a simple http request that is issued in advance by the client in order to wait a server event.
As soon as server event occurs the data getting published on the http request which leads to closing connection on issued http request. After that, client issues new http request that repeats the whole loop again.
The problem
Suppose two events happened on the server, first A then B (nearly instantly). Client gets message A which results with closing http connection. Now to get message B client has to issue second http request.
Question
If the B event happened while the client was disconnected from the server and was trying to reconnect.
Will the client get the B message automatically, or I have to invent some sort of mechanisms that will ensure message integrity?
The question applies not only to long-polling but to general situation with client reconnection.
P.S.
I'm using SignalR Hubs on the server side.
EDIT:
I've found-out that the order of messages is not guaranteed, I was not able to make SignalR loose messages
The answer to this question lies in the EnqueueOperation method here...
https://github.com/SignalR/SignalR/blob/master/src/Microsoft.AspNet.SignalR.Core/Transports/TransportDisconnectBase.cs
protected virtual internal Task EnqueueOperation(Func<object, Task> writeAsync, object state)
{
if (!IsAlive)
{
return TaskAsyncHelper.Empty;
}
// Only enqueue new writes if the connection is alive
Task writeTask = WriteQueue.Enqueue(writeAsync, state);
_lastWriteTask = writeTask;
return writeTask;
}
When the server sends a message to a client it calls this method. In your example above, the server would enqueue 2 messages to be sent, then the client would reconnect after receiving the first, then the second message would be sent.
If the server queues and sends the first message and the client reconnects, there is a small window where the second message could attempt to be enqueued where the connection is not alive and the message would be dropped at the server end. Then after reconnect the client wouldn't get the second message.
Hope this helps

what order do I get messages coming to MPI Recv from MPI_ANY_SOURCE,

I am implementing a hub/servers MPI application. Each of the servers can get tied up waiting for some data, then they do an MPI Send to the hub. It is relatively simple for me to have the hub waiting around doing a Recv from ANY_SOURCE. The hub can get busy working with the data. What I'm worried about is skipping data from one of the servers. How likely is this scenario:
server 1 and 2 do Send's
hub does Recv and ends up getting data from server 1
while hub busy, server 1 gets more data, does another Send
when hub does its next Recv, it gets the more recent server 1 data rather than the older server2
I don't need a guarantee that the order the Send's occur is the order the ANY_SOURCE processes them (though it would be nice), but if I new in practice it will be close to the order they are sent, I may go with the above. However if it is likely I could skip over data from one of the servers, I need to implement something more complicated. Which I think would be this pattern:
servers each do Send's
hub does an Irecv for each server
hub does a Waitany on all server requests
upon completion of one server request, hub does a Test on all the others
of all the Irecv's that have completed, hub selects the oldest server data (there is timing tag in the server data)
hub communicates with the server it just chose, has it start a new Send, hub a new Irecv
This requires more complex code, and my first effort crashed inside the Waitany call in a way that I'm finding difficult to debug. I am using the Python bindings mpi4py - so I have less control over buffers being used.
It is guaranteed by the MPI standard that the messages are received in the order they are sent (non-overtaking messages). See also this answer to a similar question.
However, there is no guarantee of fairness when receiving from ANY_SOURCE and when there are distinct senders. So yes, it is the responsibility of the programmers to design their own fairness system if the application requires it.

Resources