I have a problem statement where a product is making an outbound call to a self-hosted service in a synchronous way, and is expecting the response in synchronous manner.
In order to provide the response, my self hosted service needs to do a lot of async operations and goes to on-prem. On-prem sends back the response to receiver service, and while sending the response back to self-hosted service, I am not able to identify the response belongs to which request.
I have read about semaphore, and was wondering if that could be used to solve this.
For example:
Main state of each thread in Semaphore
Let the self hosted service do the usual work, and wait for something
Once I have the response from on-prem and SNS sends an event, awake to do the further processing
High-level architecture
Kindly note: I can't change the flow or the architecture
Related
I am developing a WCF RESTful web service which only accept HTTP. I have few questions about changing to async pattern.
Almost all examples that demonstrates how to use TPL to implement async WCF operation contract use client based on WCF client proxy, in my case client could be a browser that only support HTTP verbs, so it seems changing my WCF service to async pattern is not so meaningful. Can I say, if a service is RESTful and each request doesn't take very long to process, I will not benefit a lot from changing service synchronized to async?
If my service operation contracts either is a OneWay service or return nothing to client, operation contract should be defined as async Task DoSthAsync() or void DoSth()? What is the difference here? In other words, should I await/return the Task.Run or not.
My service accepts big chunk of data send from client using HTTP POST, suppose the processing would take a while, so changing to async pattern could improve service concurrency and throughput, how to make sure that the pass-in stream object is not disposed by WCF in Task.Run(() => {})delegate?
1.Almost all examples that demonstrates how to use TPL to implement async WCF operation contract use client based on WCF client proxy, in my case client could be a browser that only support HTTP verbs, so it seems changing my WCF service to async pattern is not so meaningful. Can I say, if a service is RESTful and each request doesn't take very long to process, I will not benefit a lot from changing service synchronized to async?
Question 1 is totally out since you said you want to use TPL on the WCF server side and not client side.
#CodingYoshi I have no assumption on clients. I totally focus on server side here.
.
2.If my service operation contracts either is a OneWay service or return nothing to client, operation contract should be defined as async Task DoSthAsync() or void DoSth()? What is the difference here? In other words, should I await/return the Task.Run or not.
You do not specify in your service contract whether a service is async or not. That is internal to your service. Whether your service is doing things asynchronously or not, the client can still call your service synchronously or asynchronously. For example, if your service writes stuff to a file and the writing takes 5 minutes and you have implemented to do this synchronously, the client can still call your service asynchronously (or synchronously). If you have implemented this asynchronously, then the threadpool thread which handled the call will be free to handle other calls. In other words, the changes will only be effecting the server side.
Also keep in mind, if you are doing something which is truly async then doing it asynchronously will be beneficial. If you are doing a CPU intensive operation, then doing it asynchronously will actually hurt performance. Why? Because when a request comes to ASP.NET (WCF, MVC, Web Forms or whatever) the most efficient way to handle the request is to do it using one thread-pool thread. If you are doing a CPU intensive operation then whether that thread does it, or you start a Task and another thread takes over, will be no different. However, you will pay the price for switching contexts.
3.My service accepts big chunk of data send from client using HTTP POST, suppose the processing would take a while, so changing to async pattern could improve service concurrency and throughput, how to make sure that the pass-in stream object is not disposed by WCF in Task.Run(() => {})delegate?
When a request arrives at the WCF gate, whether you handle it asynchronously or synchronously, the response will not be sent unless and until the whole operation is completed. So why would the passed in stream be disposed?
I think you are not clear on the whole async concept. Whether your service is async or not, the client will still need to make sure the calls are not blocking. For example, if the clients calls an operation, they can either:
Wait until they receive a response and do nothing else or
Call the service, do other things and once the response returns, they handle the response.
In a scale-out scenario where one server consists of master+worker endpoints and another server consists of workers, is it safe to call bus.Publish from an endpoint when it finishes handling a given event? (Keeping in mind bus.Publish could be invoked from an endpoint sitting on the worker server).
My initial reaction is that it's not safe since it sounds like the example where you should never call publish from a web server...
We could certainly use the WCF wrapper and call out to a service that exists only on the master+worker endpoint server, but does anyone have any practical experience with this?
Thanks!
Each logical subscriber has a receiving endpoint. If you're using the distributor, this is the distributor endpoint, or distributor queue, if you will. So the subscriber will subscribe to specific events and specify it's receiving endpoint. The publisher will have no idea if it's a single endpoint instance, or if it's a distributor receiving the message.
The distributor will then send the message to a worker that is ready to process the message.
This is explained in more detail and with some clarifying images on this page: http://docs.particular.net/nservicebus/scalability-and-ha/distributor/publish-subscribe
In the end, we made our web apps "send-only endpoints" which essentially means they simply send commands directly to an endpoint via a chosen transport (in our case MSMQ). Once we need to scale, we will eventually implement "Sender Side Distribution" rather than utilizing the distributor.
From the NSB support team: "If you add more endpoints, Sender Side Distribution is the way to go. It acts as a round-robin mechanism running on the sender side which would send messages to a different 'worker' endpoint when you scale out."
https://docs.particular.net/transports/msmq/sender-side-distribution
If you only need to fire-and-forget messages from a website or some other app/service, I'd recommend this approach - it's quite simple.
I have a WCF service with public REST and SOAP endpoints that has a single post method. Currently the app processes as follows
Object Posted to service method
Service method passes data to storage queue then sends an XML response.
Second worker role checks queue, does some processing and depending on processing, adds record to DB or rejects it.
My problem currently is that the WCF method responds before a decision is made to accept or reject the message. There is a lot of processing, and various worker roles are used after the WCF message is received depending on customer settings. I would like to be able to make the accept/reject decision and then respond with relevant data. I am wondering how to do this.
I could do an asynchronous Service method, but then all code would need to go into the WCF role or callable library which isn't ideal. Is there a way to not to the async End method until there is a response from another worker role (a message is in the queue)? I realize I could just do a thread.sleep and check the queue periodically, but then I would have to add the original request data to the queue and I really don't think that's the correct way to do things. I Googled this and couldn't find a concrete, non-hackish method.
Let me know if code samples would help, but (I think) it's pretty straightforward.
I have some legacy ASMX IIS hosted service. Client applications make subscribe or unsubscribe to the web service. Via some internal to the web service logic it needs to send messages to the subscribed applications periodically.
What is the best way to do the part of the long running task ? I understand opening Thread with long running task not a good idea to do under IIS.
ASMX services cannot do what you're asking for: they cannot just decide to send a message to the client. All they can do is respond if the client requests it.
You can hack around and come up with one method to start the long-running task, and another method to poll for the status of the task. This works, but it can be expensive.
The better model is to perform the long-running task in a separate Windows Service. Have that service host a simple WCF service which will only be used by the main service (the one that talks to the clients). The main (WCF) service would use a Duplex channel to communicate with the clients. That way, it can "call" the clients whenever there is news about one of the long-running tasks.
Usually in such cases when you don't have a way to push the result back, create an unique ID for the long running task and sent it back to the client, after that run the task and have a table in database or something else where you store the status of the task. The client will pull periodically the service to see the task' status by given ID. Once it finds the task is completed it will retrieve the result.
And is completely fine to have a thread running inside IIS doing its job.
I have a c# WCF web service which is a server and I do have 2 clients one is java client and another is c++ client. I want both the clients to run at the same time. The scenario I have and am unable to figure it out is:
My java client will be making a call to the WCF web service and the processing time might take around 10 mins, meanwhile I want my c++ client to make a call to the web service and the get the response back. But right now I am just able to make a call to web service using c++ client when the java client request is being processed. I am not getting the response back for c++ client request until java client request is completed.
Can any one please suggest me how to make this work parallel. Thanks in advance.
Any "normal" WCF service can most definitely handle more than one client request at any given time.
It all depends on your settings for InstanceContextMode:
PerSession means, each session gets a copy of the service class to handle a number of requests (from that same client)
PerCall means, each request gets a fresh copy of the service class to handle the request (and it's disposed again after handling the call)
Single means, you have a singleton - just one copy of your service class.
If you have a singleton - you need to ask yourself: why? By default, PerCall is the recommended setting, and that should easily support quite a few requests at once.
See Understanding Instance Context Mode for a more thorough explanation.
Use
[ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple )]
attribute over your service class. More on this for example here:
http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and
This is peripheral to your question but have you considered asynchronous callbacks from the method that takes 10+ minutes to return, and then having the process run in a separate thread? It's not really good practice to have a service call waiting 10 minutes synchronously, and might solve your problem, although the service should allow for multiple callers at once anyway (our WCF service takes thousands of simultaneous requests).
When you call a WCF you have a choice in either calling it synchronously or asynchronously. A synchronous call waits for the response to send back to the caller in the same operation. In the caller it would look like "myresult = svc.DoSomething()". With an asynchronous call, the caller gives the service a function to call when it completes but does not wait for the response. The caller doesn't block while waiting for the response and goes about its business.
Your callback will take DoSomethingCompletedEventArgs:
void myCallback(object sender, DoSomethingCompletedEventArgs e)
{
var myResult = e.Result;
//then use the result however you would have before.
}
You register the callback function like an event handler:
svc.DoSomethingCompleted+=myCallback;
then
svc.DoSomethingAsync(). Note there is no returned value in that statement; The service would execute myCallBack when it completes and pass the result. (All WCF calls from Silverlight have to be asynchronous but for other clients this restriction isn't there).
Here's a codeproject article that demonstrates a slightly different way in detail.
http://www.codeproject.com/Articles/91528/How-to-Call-WCF-Services-Synchronously-and-Asynchr
This keeps the client from blocking during the 10+ minute process but doesn't really change the way the service itself functions.
Now the second part of what I was mentioning was firing off the 10+ minute process in a separate thread from inside the service. The service methods themselves should be very thin and just be calling functionality in other libraries. Functions that are going to take a long time should ideally be called in their own threads (say a backgroundworker, for which you register on the service side a callback when it completes) and have some sort of persistent system to keep track of their progress and any results that need to go back to the client. If it were me I would register the request for the process in a db and then update that db with its completion. The client would then periodically initiate a simple poll to see if the process was completed and get any results. You might be able to set up duplex binding to get notified when the process completes automatically but to be honest it's been a few years since I've done any duplex binding so I don't remember exactly how it works.
These topics are really too big for me to go into depth here. I would suggest researching multithreaded operations with the BackgroundWorker.