How to process Queued WCF Web service requests - wcf

I have a requirement to Queue web service requests and then process each request based on priority and request time. And then send response back.
The approach I'm thinking is as follows
1 Create a web service method to submit requests and enqueue requests.
2 Create two queues (high priority requests and lower priority requests)
3 Create a Processing method to process each request one at a time(dequeue the high priority queues first if it exists) process and then store the response
4 Create a dictionary to store response for the respective request.
5 create a web service method to get the response
I'm thinking to use in memory queue since I expect few number of requests queued at a time.
The problem I'm having is in step 3. I want the processor method to continuously run as long as there are requests in the queue.
How can I accomplish step 3 using WCF web service ?
I'm using .NET 4.0 environment.
I really appreciate any ideas or suggestions.
Thanks

I would create my service contract to make it clear that the operations will be queued. Something like:
[OperationContract]
string EnqueueRequest(int priority, RequestDetails details);
[OperationContract]
bool IsRequestComplete(string requestId);
I would have EnqueueRequest place each request into an MSMQ queue. I'd have a Windows Service processing the requests in the queue. That service would be the only process that has access to the SDLC device.

Have you coded the service in a plane jane, meat and potatoes way and profiled to see if it's necessary to queue requests? There is overhead involved in queuing. It's a good idea to do some measurement and see if just servicing requests is adequate.
Another way to approach it would be to use Microsoft Message Queue. Here is even some tight integration between message queues and WCF. The thought is, if you do actually need a queue, why not use something that is already built and tested.

Related

Scaling RabbitMQ-based microservices in Nestjs

I need to create a RabbitMQ-based microservices solution in Nestjs. To scale the system, I need to deploy several instances (e.g., 3 dockers) of the same microservice (server) listening to the same RabbitMQ topic, processing requests coming from the consumer (client) (see the following figure). I assume these 3 instances use a kind of Round Robin to pop up messages/requests from the queue/topic and process them and then return the results in another queue (i.e., 'callback' queue) to the consumer. I am wondering if
Nestjs already handles the correlation_id (to correlate responses with requests | to tackle the issue, having received a response in that queue it's not clear to which request the response belongs.) under the hood, or do I need to extend the current library?
Does NestJs create an exclusive callback queue (when several instances of the same microservices are deployed) or do I need to take care of that myself in my code (i.e., The worker (aka: server | microservice) is waiting for requests on that queue. When a request appears, it does the job and sends a message with the result back to the Client/Consumer, using the queue from the reply_to field.). In other words, The client (consumer) waits for data on the callback queue. When a message appears, it checks the correlation_id property. If it matches the value from the request it returns the response to the application.

TransX WCF and Multithreading

I have some queries about WCF and multithreading.
My plan is to place items onto the Thread Pool and for it to process messages from the MSMQ queue.
I also will be hosting WCF in WAS.
I am wondering how the threading will work at this point. For example messages will be picked up by the WCF binding to the MSMQ queue and I know that WAS will spin up the service as and when it requires to. But lets say if we have 100 messages to process (100 messages per second for example) - would these be delivered in a threaded way or in a single thread?
If in a threaded manner then how best to commit or abort transactions? Any special considerations?
Sorry for the questions - just need to clarify this.
Its not clear what "placing items onto the Thread Pool" does but on the WCF side, a service using the netMsmqBinding handles "calls" in a similar way as other WCF bindings. The difference is that a "call" is actually an MSMQ message in a queue.
This article on netMsmqBinding gives a very clear explanation of how the binding works. If you configure the WCF service with its default InstanceContext setting (per call or per session depending on the .NET version), the service instances will pick up messages off the queue as-if they were a standard call each. There are setting in MSMQ and WCF that can affect this behavior to make the messages be processed sequentially but that's not the default.
Let WCF handle multi-threading for you by leaving the service set to per call (or per session) and for transactions, look at the code in this sample in MSDN to see how to work with them.

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 Design example

I have to create a WCF service that will accept thousands of requests every 5 minutes, which each request passing a small (1-5KB) text file.
The service will pass the file contents to another assembly, which will process the lines and insert some records into the database. Nothing too heavy on this side.
I need help on the following aspects:
Which WCF configuration should I use that will give me the best performance? The calls to the service will come from the internet not an internal LAN.
The service will accept requests every 5 minutes, which means I have only 5 minutes to process all the requests before the next cycle. Is MSMQ the best solution here?
Any examples online I can read?
For best performance, I'll assume you're talking about less latency. You should pick a TCP transport, like net.tcp. This document can help you to decide Choosing a Transport
About that MSMQ part: you'll receive a lot request and just start processing them after 5 minutes? If yes, your choice is correct: MSMQ will keep that request queue and you can work on them asynchronously.
Use NetTCPbinding
Optimizing WCF Web Service Performance
Creating high performance WCF services

REST, WCF and Queues

I created a RESTful service using WCF which calculates some value and then returns a response to the client.
I am expecting a lot of traffic so I am not sure whether I need to manually implement queues or it is not neccessary in order to process all client requests.
Actually I am receiving measurements from clients which have to be stored to the database - each client sends a measurement every 200 ms so if there are a multiple clients there could be a lot of requests.
And the other operation performed on received data. For example a client could send an instruction "give me the average of the last 200 measurements" so it could take some time to calculate this value and in the meantime the same request could come from another client.
I would be very thankful if anyone could give any advice on how to create a reliable service using WCF.
Thanks!
You could use the MsmqBinding and utilize the method implemented by eedsi9n. However, from what I'm gathering from this post is that you're looking for something along the lines of a pub/sub type of architecture.
This can be implemented with the WSDualHttpBinding which allows subscribers to subscribe to events. The publisher will then notify the user when the action is completed.
Therefore you could have Msmq running behind the scenes. The client subscribes to the certain events, then perhaps it publishes a message that needs to be processed. THe client sits there and does work (because its all async) and when the publisher is done working on th message it can publish an event (The event your client subscribed to) letting you know that its done. That way you don't have to implement a polling strategy.
There are pre-canned solutions for this as well. Such as NService Bus, Mass Transit, and Rhino Bus.
If you are using Web Service, Transmission Control Protocol (TCP/IP) will act as the queue to a certain degree.
TCP provides reliable, ordered
delivery of a stream of bytes from one
program on one computer to another
program on another computer.
This guarantees that if client sends packet A, B, then C, the server will received it in that order: A, B, then C. If you must reply back to the client in the same order as request, then you might need a queue.
By default maximum ASP.NET worker thread is set to 12 threads per CPU core. So on a dual core machine, you can run 24 connections at a time. Depending on how long the calculation takes and what you mean by "a lot of traffic" you could try different strategies.
The simplest one is to use serviceTimeouts and serviceThrottling and only handle what you can handle, and reject the ones you can't.
If that's not an option, increase hardware. That's the second option.
Finally you could make the service completely asynchronous. Implement two methods
string PostCalc(...) and double GetCalc(string id). PostCalc accepts the parameters, stuff them into a queue (or a database) and returns a GUID immediately (I like using string instead of Guid). The client can use the returned GUID as a claim ticket and call GetCalc(string id) every few seconds, if the calculation has not finished yet, you can return 404 for REST. Calculation must now be done by a separate process that monitors the queue.
The third option is the most complicated, but the outcome is similar to that of the first option of putting cap on incoming request.
It will depend on what you mean by "calculates some value" and "a lot of traffic". You could do some load testing and see how the #requests/second evolves with the traffic.
There's nothing WCF specific here if you are RESTful
the GET for an Average would give a URI where the answer would wait once the server finish calculating (if it is indeed a long operation)
Regarding getting the measurements - you didn't specify the freshness needed (i.e. when you get a request for an average - how fresh do you need the results to be) Also you did not specify the relative frequency of queries vs. new measurements
In any event you can (and IMHO should) use the queue (assuming measuring your performance proves it) behind the endpoint. If you change the WCF binding you might still be RESTful but will not benefit from the standard based approach of REST over HTTP