How does WCF Reliable Sessions affect message ordering? - wcf

One of the things that the Microsoft documentation says about enabling reliable sessions is that the service will be able to process messages in the order that they were received.
Does this mean that messages within a single session are processed in order? Or does it mean that all messages for all sessions within the service are processed in order?
I know that netTcpBinding is reliable already, without enabling reliable sessions. However, say you use something like WsDualHttpBinding without reliable sessions enabled... is it possible that if the client sends request A and then sends request B that the service might receive B before A? Or does it mean that if client A sends message A and client B sends message B, that I might process B before A?

The service might receive B before A, but reliable sessions will place the messages in a buffer and only process them in the order they were sent within the session. It will not gaurentee order between different sessions, only within the same session that is created by the client.

Related

Scatter Gather : Wait for all "Gather-Workers" to complete [duplicate]

I've configured a rabbitmq fanout exchange called "ex_foo" for a RPC workload. When clients connect to the server, they create their own non-durable RPC receive queue and connect to it with a BasicConsumer. The apps listen for messages/commands and respond to the queue defined in the reply_to part of the request.
One of the simple messages/commands I'm sending out the the fanout exchange (and thus, every application/client connected to it) is a type of ping request message, and my problem is that I don't know how many ping responses I will get (or should expect), because I don't know how many clients are connected to the fanout exchange at any one time. All clients connected to the fanout exchange should reply.
If gets delivered to 10 queues on the fanout exchange (ie: 10 clients are connected), how do I know how many responses to expect? In order to know that, would I have to know how many times it was delivered? Is there anything more sophisticated and a sleep timer? Simply, my admin tool can't just wait indefinitely and needs to quit after it has recveived all pings (or a time-out has elapsed).
What you are looking for is something like a Scatter-Gather (http://www.eaipatterns.com/BroadcastAggregate.html) pattern, isn’t it?
You don’t know the consumers bound to the fan-out, so you can:
implement an keep-alive from the consumer(s) using for example an queue where the producer is bound.
Each consumer sends a keep-alive each one second, if you don’t receive a message you can considerer the consumer off-line.
Use an in-memory database where the consumer are registered (always with a keep-alive).
Use the HTTP API to know the consumers list bound to the fan-out, in this way:
http://rabbitmqip/vhost/yourfanout/bindings/source and the result is like this:
[{"source":"yourfanout","vhost":"/","destination":"amq.gen-xOpYc8m10Qy1s4KCNFCgFw","destination_type":"queue","routing_key":"","arguments":{},"properties_key":"~"},{"source":" yourfanout","vhost":"/","destination":"myqueue","destination_type":"queue","routing_key":"","arguments":{},"properties_key":"~"}]
Once count the consumers you know the replies count.
Call the API before send a request.
NOTE the last-one can works only if you use a temporary queue bound to the consumers.
I found this resource that could help you (http://geekswithblogs.net/michaelstephenson/archive/2012/08/06/150373.aspx)
I don't know exactly your final scope, but with a keep-alive you can wait max one second before decide if the consumer is alive.

Bulk calls vs multiple calls in WCF using MSMQ

I am calling a WCF service which contains the business logic to process the message objects.
I need to pass the id of the message to WCF service. We are using MSMQ for queuing up the requests.
There could be multiple messages that WCF service need to process which can be handled as follows
Send the message id one by one
Send array of message ids and then WCF service will iterate through each id and process the message object.
Performance point of view I believe second option is better as multiple requests to WCF are not there.
Is my assumption correct?
-
Ram
Number 2 is more efficient in terms of latency but does not give you the chance to spread the processing load by having multiple queue readers
Also be aware that if you use a transactional queue and sessions then WCF may put more than one SOAP message in each MSMQ message

WCF service writes log only if client receives results

I'm working on a WCF service to help our new code interoperate with a legacy system. The process goes like this:
Client calls the service with a request for the legacy system.
Service writes the request into a database.
Legacy system services request from the DB in its own time and writes results back into the DB (updating a status flag to say results are ready).
Client retrieves results by calling a second service method, which polls the DB until the ready flag is set.
Just before returning the results, the service updates the status flag to client has results, so that the related DB rows can be deleted.
My concern is the race condition at the last step. I can see this happening:
Service updates status to client has results.
Client times out after waiting for the service to poll the DB.
Service tries to return results. Hilarity ensues.
One way to solve this would be to have three service calls instead of two: the second call retrieves results, and the last one is an explicit acknowledgement by the client that it has them. I'd like to know whether there is a way which doesn't impose this extra "protocol" burden on the client though.
I've looked briefly into using transactions in WCF, and it sounds like they might be able to do what I need. The client (optionally) starts a transaction, flows it to the service, which uses it if it's there, and commits it when done. This seems as if it implicitly does the "third call".
Does this idea have any merit? Any disadvantages that you can see? Are there any other avenues I could explore?
Using transaction flow is possible but flowing transaction in polling scenario (in each poll call) is terrible architecture. What you generally need is transaction flow for the real read operation where service modifies the record and returns data back to the client. The client will commit the transaction and it will commit changes performed by the service.
Using transactional processing places some additional requirements on your service and clients.
Another approach can be transactional MSMQ:
Client calls the service with a request for the legacy system = client sends a message to the service's queue
Service writes the request into a database = service processes the message from its queue
Legacy system services request from the DB in its own time and writes results back into the DB (updating a status flag to say results are ready).
Service polls the database and places messages to correct client queues. Placing the message and modifying database records runs in transaction
Client processes incoming message
Transactional queue allows transactional reading (the message is removed from the queue only if transaction is committed) and writing (the message is added to the queue only if transactions is committed). That will allow deleting records before the client reads the message because the message will remain in the queue until he successfully reads it (or until it timeouts and even after that it can be passed to some error queues).
In both cases you should think about clients who will consume the service. Transaction flowing can be interoperable but not every web service stack supports it. MSMQ is not interoperable.
Why not reduce the likelihood of the client timing out by doing this instead:
Client calls service with a request for the legacy system.
Service writes the request into a database.
Legacy system services request from the DB in its own time and writes results back into the DB (updating a status flag to say results are ready).
Client calls a service to find out whether the results are ready. NB. no polling: just returns with an immediate yes or no.
If the results are NOT ready, client waits a bit and then goes back to step 4.
If the results ARE ready, call the service to retrieve the results. The service can update the status to "Client has results" at that point.
By doing this, the client won't be waiting for the service call in step 4. to return for a prolonged period, and the chances of a timeout should be minimal.
However, you're never going to be 100% certain that the client has received the results unless the client makes a final service call to say so. (What if, for example, the client dies after making the very last request?)

Preserving order of messages in WCF service with ConcurrencyMode.Multiple mode

There is a WCF service which handles incoming requests and for each incoming message produces a corresponding output message which is sent to another WCF service. The order in which messages come is important and cannot be disturbed. So the service should produce the corresponding output messages in the same order in which they are received by the service. Also it's important to handle requests concurrently so that to benefit from multicore CPU.
What is the best approach to preserving order of messages between inputs and outputs in this case?
That is completely up to your implementation. WCF can only enforce ordered delivery (either through reliable session or MSMQ) so that you can be sure that messages are received in the order they were sent but there is no feature which will ensure that your operation will send messages in the same order (one message can be processed faster then another received earlier). If you want to process messages in order setting ConcurrencyMode to Multiple will only make things terribly complicated. You will have to manually synchronize operations which will reduce concurrency and in the worst case fallback close to ConcurrencyMode.Single. Synchronization can be hard to achieve because it is not enough to do it in the operation - WCF channel stack processing of output messages must also be synchronized.

Why are my message be processed out of order over a single WCF TCP channel (with ConcurrencyMode.Reentrant)?

The client sends a lot of messages to the server from a single thread, over a single WCF channel.
The client sends the message with BeginMyMethod(x, b) as it does not wish to block while they get processed.
We have reliable messaging turned on, as we don’t wish to lose any messages, or have them get out of order.
However the messages are being despatched on multiple threads on the server, so are being process out of order.
We can’t have the server being single threaded, as we don’t wish a long running request from one client to block other clients.
So I just wish to process all the messages that come from a single client (over a single channel) in order with only one message from each cleint being processed at a time.
This would be easy for raw socket programming, however how to I get WCF to work as I wish?
I am now thinking that ConcurrencyMode.Reentrant does not behave well when used with InstanceContextMode.Single If I set use ConcurrencyMode.Single the messages are kept in order, but my call-backs deadlock.
(The test that gets the messages out of order has no callbacks and does not make any outgoing WCF calls, so I would expect ConcurrencyMode.Reentrant to behave the same as ConcurrencyMode.Single in that given test, but it does not)
I a not using any WCF config files, the code is:
serviceHost = new ServiceHost(this);
serviceHost.AddServiceEndpoint(
typeof(IAllEngineManagersAsyncCallbacks),
new NetTcpBinding(SecurityMode.None, true),
endPointAddress);
I have now worked round this problem by:
Changing all my call-backs from the server to the client to be OneWay
Using a dispatcher in the client before passing on any callback from the server, so client code never calls the sever from within a call-back
The client call-back object is marked with CallbackBehavior(UseSynchronizationContext=false, ConcurrencyMode=ConcurrencyMode.Single)
When running in Winform or WPF I use SynchronizationContext.Post to depatch the callbacks
When the cleint is a Console or a Windows server I use a custom depatcher.
So letting me use ConcurrencyMode.Single on both the server and the client.
It is now working as expected.
(BeginMyMethod(x, b) is still being used to send messaged from the client to the server)
(ConcurrencyMode.Reentrant seems to sometimes release the lock even when the WCF call is not made on the some thread that is processing the incoming message, it is just not a useful as Reentrant was in DCOM)
If you are using the generated BeginXXX async-methods, these are executed on a ThreadPool thread.
So although you've send the messages in a defined order, nobody guarantees you in which order the ThreadPool executes the requests.
I think that Reentrant mode implies that you allow messages be processed out of order. Normal behavior of such service would be: get message, put in queue for internal threads to process, and when it's done notify client about result. So maybe your service get messages in proper order but some of them are quiker to process and return earlier than others?