Reputation: 4114
Since it's a long question, cliff notes come first.
Cliff notes:
One client sends input to several services and they keep on working and sending results until the client tells them to stop or they have reached a pre-set maximum number of results.
Do you know how one should go about implementing this, or do you have a C#-example for sth. like this? Is WCF & streaming the right toolset for this ? (Consider that results are custom objects, so it's not exactly the same as streaming a file)
More Detailed Problem Definition:
Situation:
I mention solutions A+B since I think they help explaining the problem:
Solution (A) - The slow non-parallel way:
1. Client sends input to one service.
2. Service initializes based upon the input.
3. Service processes all 1000 pieces of work
(results get added up(super fast btw) so the result of 1000 pieces of work has the same size as the result of one)
4. Service sends result to the client.
5. Client receives result and is happy
Solution (B) - Parallel faster way:
Let's say ten services, so we evenly split it up and each should process 100.
The problem is some services may be much faster than others so giving each the same number(100) is slower than necessary. Furthermore we can't split up according to an a priori speed-test since the speed of one service can change and some might even go down during processing, these are the reasons why I think the following would be best for my purpose.
Solution (C) - The way I would like to implement it:
Client sends out the same request to all services. (same request still implies that the task get's processed in parallel, parallelization is super easy for my problem 1000 pieces of work are so independent that doing 1000 times the "first" piece of work means we are done)
A service keeps working and sending results until it is told to stop or has processed 1000 pieces of work. One result gets sent for 10 pieces of work done. This means all services work parallel on the task and when the client has gotten a sum of 1000 results from all service replies combined it will send the stop signal. That means normally no single service should reach 1000, but with having 1000 we have covered the situation where there is only one service and we have a fail-safe to avoid infinite loops if the stop signal gets lost. (client neither needs to wait nor to be absolutely sure that the stop signal has reached a service)
Throwing away additional results beyond our goal of 1000 is fine.
(The alternative of instead making follow-up requests to services that have responded faster than others would come with the overhead of wasted time due to messages going back and forth and additional initializations. (Add. inits could be avoided but it would be complicated and you still have the other overhead))
I basically have solutions/would know how to implement A+B but I have no clue how I would go about realizing (C). How do you implement a client/service-architecture in C# where the service keeps sending results and doesn't just return one object/value? (Results are custom objects, btw) Does someone know about C#-example-code where sth. like that is implemented? Would streaming be the right way?
I've found the "writing a custom stream"-example but it seems like it's a pretty long way from there to what I want. (As a WCF-noob I can easily be wrong on that though.)
Upvotes: 3
Views: 1865
Reputation: 364369
Streaming in the WCF doesn't work in the way that you will open a stream, return the stream to the client and service will still generate results to the stream. If you want to work this way you must go deeper and use sockets directly. In WCF the stream must be written prior to returning it from the operation (I tried to write to returned stream from other thread but it didn't work). Streaming in WCF is only for data transport.
I don't like any of your solution. I would try:
Edit:
Ok because of your clarification it looks like you need to send the same task to multiple services and task will just trigger series of the same computation on the same data. You can achieve it in this way:
IsInitiating
and IsTerminating
properties of OperationContract
)Here is an example of using duplex services with WsDualHttpBinding
- don't use this binding in your scenario because it is much more complicated if you want to have single client to communicate with multiple same services over duplex HTTP.
Upvotes: 4
Reputation: 4570
What you describe as Solution (C) sounds like a good use for Asynchronous WCF. Some of these might help...
Synchronous and Asynchronous Operations
Asynchronous Programming Design Patterns
How to: Call WCF Service Operations Asynchronously
Upvotes: 0