Consider a web application that implemented every database action except querying (i.e. add, update, remove) as a NServiceBus message, so that whenever a user calls a web API, in the back-end it will be mapped to await endpointInstance.Request method to return the response in the same HTTP request connection.
The challenge is when a message handler needs to send some other messages and wait for their response to finish its job. NServiceBus does not allow to call Request inside a message handler.
I ended up using Saga to implement message handlers that are relied on some other message handler responses. But the problem with Saga is that I can't send back the result in the same HTTP request, because Saga uses publish/subscribe pattern.
All our web APIs need to be responded in the same HTTP request (connection should be kept open until the result is received or a timeout exception occurred).
Is there any clean solution (preferably without using Saga)?
An example scenario:
user call http://test.com/purchase?itemId=5&paymentId=133
web server calls await endpointInstance.Request<PurchaseResult>(new PurchaseMessage(itemId, paymentId));
PurchaseMessage handler should call await endpointInstance.Request<AddPaymentResult>(new AddPaymentMessage(paymentId));
if the AddPaymentResult was successfull, store the purchase details in the database and return true as PurchaseResult, otherwise return false
You're trying to achieve something that we (at Particular Software) are trying to actively prevent. Let me explain.
With Remote Procedure Calls (RPC) you call another component out-of-process. That what makes the procedure call 'remote'. Where with regular programming you do everything in-process and it is blazing fast, with RPC you have the overhead of serialization, latency and more. Basically, you have to deal with the fallacies of distributed computing.
Still, people do it for various reasons. Sometimes because you want to use a WebAPI (or 'old fashioned' web service) because it offers the functionality you don't want to develop. Oldest example in the book is searching for an address by postal code. Or deducting money from someone's bank account. If you're building a CRM, you can use these remote components. These days a lot of people build distributed monoliths because they are taught at conferences that this is a good thing. In an architecture diagram, it looks really nice, but there's still temporal coupling that can provide a lot of headaches.
Some of these headaches come from the fact that you're trying to do stuff in an atomic action. Back in the days, with in-process calling of code/classes/etc this was easy and fast. Until you hit limitations, like tons of locks on a database.
A solution to this is asynchronous communication. You send some information via fire-and-forget. This solves temporal coupling. Instead of having a database that is getting dozens and dozens of requests to update data, etc. and as a result, your website is grinding to a halt, you have various options to make sure this doesn't happen. This is a really good thing, because instead of a single atomic operation, you have various smaller operations and many ways to distributed work, scale your system, etc, etc.
It also brings additional challenges, because not everyone is able to work with fire-and-forget. Some systems that were already built, try to introduce asynchronous communication via messaging (and hopefully NServiceBus). Some parts can work flawlessly with this. But others parts can't. Mainly the user-interface (UI). Because it was built to get an immediate result. So when you send a message from the UI, you expect a result!
With NServiceBus we've built a package called "Client-Side Callbacks" to make exactly this a possibility. We highly recommend our customers not to use it, except for this specific scenario that I just described. It is much better to migrate your entire UI to be able to deal with the fact that you don't receive an immediate answer, but we understand this is so much work, that not many will be able to achieve this.
However once that first message was sent and the UI received a result, there is no need to use callbacks anymore. As a result I'd like to propose this scenario:
use call http://test.com/purchase?itemId=5&paymentId=133
web server calls await endpointInstance.Request<PurchaseResult>();
PurchaseMessage handler retrieves info it needs and sends or publishes a message to (an)other component(s) and then replies back to the web server with an answer.
The next handler works with the send/published message and continues the process
Let us know if you need more information. You can always contact us by sending an email to support#particular.net
Related
I'm trying to figure out how to implement a fault-tolerant message publication solution using MassTransit. We'll focus on the simple scenario where we only need to commit a database change, and publish an event indicating that change. Because there is no (built-in) mechanism that allows an atomic "commit and publish", when our process crashes, we will get into an inconsistent state (some messages would only be committed to the database, and some might only be published to the message queue).
This documentation page offers a solution, where because we assume message handling is idempotent, we can rely on the entire operation to be retried in case of failure, and these partial commits will be resolved eventually. This is a great solution, but it only has one caveat: it assumes that the operation we are performing was triggered by a message, and if we won't send an ack, processing will be retried. This is not a reasonable assumption, as messaging is typically used only for internal communication inside the system, not for communication with the outside world. What should I do when I need to save-and-publish when handling an HTTP request from an external client?
One possible solution is to hack our way into the approach presented in the article, by only publishing (or sending) a message, and listening to it ourselves, then in the message handler we do the commit and the publishing of the actual event we want others to listen to. The main problem I have with this is that it assumes we never have to return anything in the HTTP response. What if we need to indicate the success or failure of the database transaction back to the HTTP client? (example: if we rely on a UNIQUE constraint to tell us whether or not we should accept the request, and we want to indicate failure to the client). We could solve it by using request-response over the message queue (with ourselves), but this is ugly and increases latency and complexity considerably, for what is actually a very common scenario.
The approach I see the most over the internet to solve this problem, is to use an outbox that is persisted to the same database we need to write to anyway, and thus we can wrap the two operations in a regular ACID database transaction. Then a background task polls this database for new events and publishes them to the message broker. Unlike other frameworks, I understand that MassTransit does not support this behavior out of the box. So I guess my question boils down to: before rushing to implement this relatively complex mechanism myself (once per database technology), is there another solution I'm missing? what is the accepted solution to this problem in the MassTransit community?
This has been asked several times, in a variety of forms, here and other places. But the short answer is simple.
In your controller, write to the message broker only. Let the consumer deal with the database, in the context of consuming a reliable message, with all the nice retry and redelivery options that are available in that context. Then you get all the benefits of the InMemoryOutbox, without adding extreme complexity related to having a third-party (HTTP, database, and broker) in a single conversation.
I have an endpoint which returns the response containing hotels and a flag which shows more results are available, the client needs to call this endpoint recursively till the time the server returns more results flag as false. What is the better way to implement this? Could anyone help me on this?
First Option: Avoid It If Possible
Please try to avoid calls on HTTP APIs so as to avoid network latency.
This is very important if you want to make multiple calls from a client which is supposed to be responsive.
e.g. if you are developing a web application / WPF application and you want user to click on something which triggers 10-20 calls to API, the operation may not complete quickly may result in poor user experience.
If it is a background job, then probably it multiple calls would make more sense.
Second Option: Optimize HTTP Calls From Client
If you still want to make multiple calls over HTTP, then you will have to somehow optimize the code in such a way that at least you avoid the network latency.
For avoiding network latency, you can bring all the data or major chunk of the data in one call on the client side. Then client can iterate over this set of data.
Even if you reduce half of the calls you buy much more time for client processing.
Another Option
You can also try to think if this can be a disconnected operation - client sending just one notification to server and then server performing all iterations.
Client can read status somewhere from database to know if this operation is complete.
That way your client UI would still say responsive and you will be able to offload all heavy processing to Server.
You will have to think and which of these options suits High Level Design of your product/project.
Hope I have given enough food for thoughts (although this may not be solving your issue directly).
I'm trying to design an application that will allow two users over a network to play the prisoner's
dilemma game (http://en.wikipedia.org/wiki/Prisoner%27s_dilemma).
Basically, this involves:
Game starts (Round 1).
Player 1 chooses to either cooperate, or betray.
Player 2 chooses to either cooperate, or betray.
Each other's decisions are then displayed
Round 2 begins
Etc.
I've done some thinking and searching and I think the application should contain the following:
Server class that accepts incoming tcp/ip connections
Gui clients (Seperate program)
For each connection (maximum 2) the server will create a new ConnectedClient class. This class will contain the details of the two player's machines/identities.
The Server class and the ConnectedClient class will connect/subscribe events to each so they can alert one another when e.g. server instruction ready to transmit to players, or players have transmitted their inputs to the server.
I'm not sure whether the best approch is to use a single thread to do or the work, or have it multithreaded. Single threaded would obviously be easier, but I'm not sure whether it is possible for this situation - I've never made a application before requiring TCP/IP connections, and I'm not sure if you can listen for two incoming connections on one thread.
I've found the following guide online, but it seems that it opens two clients on two threads, and they communicate directly to each other - bypassing the server (which I will need to control the game logic): http://www.codeproject.com/Articles/429144/Simple-Instant-Messenger-with-SSL-Encryption-in-Cs
I'm very interested and would be grateful on any advice on how you would go about implementing the application (mainly the server class).
I hope I've explained my intentions clearly. Thanks in advance.
My 1st advice would be to forget about TCP/IP and sockets here. You definitely can do it with that technology stack, but you would also get a lot of headache implementing all the things you want. And the reason is it too low level technology for such a class of tasks. I would go with tcp/ip and sockets only for academic interest, or if I need tremendous control over the communication, or if I have very high performance requirements.
So, my 2nd advice would be to look at WCF technology. Don't be afraid if you haven't used it before. It's not that difficult. And if you were ready to use sockets for your app, you can handle WCF definitely. For you task you can create basic communication withing 1-2 hours from scratch using any WCF tutorial.
So, I would create a server WCF service which will have some API functions containing your business logic. It can be hosted within a windows service, IIS, or even a console application.
And your clients would use that WCF service, calling their functions like it's functions from another local class in your project. WCF could also help you do the events which you want (it's a little bit more advanced topic though). And you can even forget about threading here, most of the things will be working out of the box.
First, as others have said, separate your game logic as much as you can, so the basic funcionality won't depend too much on your comunication infrastructure.
For the communication, WCF can handle the task. You can make your clients send a request to a service hosted in IIS, doing some kind of identification/authentication, and open a Duplex channel from where your service can push results and comunicate the start of new rounds.
Once one client connects, it waits for another. When it happens, it notifies the first client using the Duplex Channel callback and awaits for its choice. Then it asks the second user, awaits for its response. When it comes, it notifies the result to both and restarts the game.
Going a little bit deeper in the implementation:
You will have a service with some operations (like Register, PushDecision, more if needed). You will also define a callback interface, with the operations your service will need to push to the client (NotifyResult, RequestDecision, again, these are examples). You then create proxies for your clients that maps to your service operations and implement the callback operations in a way it expose events and raise them when the service pushs messages.
A use case:
Client A creates the proxy, calls Register on the server. The server receives the call, register the cilent and saves the callback object in a state. A duplex connection will be established. What does that mean? It means that (if you using the PollingDuplexBinding, as you probably will) from now on the proxy object in Client A will be doing long poll requests to the server, checking if there is a callback message. If there isnt, then it long polls again. If there is, it calls the method of the callback in the proxy passing the data the server has push. The callback method in the proxy will tipically raise an event, or execute a delegate, its up to you to choose.
Client B connects (calling Register), does the same as it did to A, and the server, noticing that two clients are connected, requests a response to A through its saved callback. This can happen during the processing of the B's Register call, or it can be triggered to execute in a new thread (or better, run in the ThreadPool or start a new Task) in B's register call.
Client A will receive the server callback requesting its choice. It can then notify the user and get the choice through the UI. A new call is made to the server (PushDecision, for example). The server receives Client A choice, asks B the same way. Once it has both responses, it calculates the result and pushes the outcome to the Clients.
An advantage of using Duplex Channels with PollingDuplex with WPF is that, as it uses long polling, there will be no need to use other ports than 80.
This is by no means a final implementation, is just a little guide to give you some ideas instead of just giving you some misty advices. Of course, there may be a bunch of other ways of doing that with WCF.
We can first assume that the application can handle only two users per time and then, if you want, you can scale up, making your service keep some form of state with a mapping table with locked access, as another example.
Some thoughts on WCF: There is an easy path to start developing with WCF using the Visual Studio tools (svcutil) but I don't like that approach. You don't "get to know" the WCF infrastructure well, you become tied to the verbose magic with which it generates your proxies, and you lose flexibility, especially in special scenarios, like Duplex polling that you may want to use.
The other way, that is to manually create your services and your proxies, is not that hard, though, and gets very interesting once you realize what you can do with it. Related to that I can give you one advice: do everything you can to make your proxy operations use Task-based Async Pattern (you can see the different ways to implement proxy operations here). This will make your code much cleaner and straight forward when combined with the new C# async/await keywords and your UI will be a joy to implement.
I can recommend some links to get you started. Some of them are old, but very didactic.
There used to be a fantastic article of WCF in this link but it seems to be now offline. Luckily, I found the content available there in a file in this link.
This one covers your hosting options.
Topics on WCF infrastructure: link
Topics on Duplex Services: link link link
Topics on Task-based Async Pattern: link link link
Well one advice I can give you if you insist that all user communicate through server and you want your application to scale:
Separate your logic (by understanding each part of the logic you want to build on the server)
Make your classes such that it can handle multiple users per transaction
Use IOCP whenever possible
it depends on the structure of your application if you need authentication and user profiles etc .. you may introduce the WCF or whatever web-service for user and hide your actual action in the background (this will cost you performance but it might be the only suitable solution you have) , so you may have your authentication framework at the top of your server logic, and a pipelined action logic in the behind .. i.e. users get authenticated to be able to access the services presented by the server, but these services pipeline all users and handle as many as possible simultaneously — if you don't need authentication then you might directly communicate to your server logic and you may use completion ports on user's request - a lot of work to be done here.
I'm tasked to create a web application. I'm currently using c# & asp.net (mvc - but i doubt its relevant to the question) - am a rookie developer and somewhat new to .net.
Part of the logic in the application im building is to make requests to an external smsgateway by means of hitting a particular url with a request - either as part of a user-initiated action in the webapp (could be a couple of messages send) or as part of a scheduledtask run daily (could and will be several thousand message send).
In relation to a daily task, i am afraid that looping - say - 10.000 times in one thread (especially if im also to take action depending on the response of the request - like write to a db) is not the best strategy and that i could gain some performance/timesavings from some parallelization.
Ultimately i'm more afraid that thousands of users at the same time (very likely) will perform the action that triggers a request. With a naive implementation that spawns some kind of background thread (whatever its called) for each request i fear a scenario with hundreds/thousands of requests at once.
So if my assumptions are correct - how do i deal with this? do i have to manually spawn some appropriate number of new Thread()s and coordinate their work from a producer/consumer-like queue or is there some easy way?
Cheers
If you have to make 10,000 requests to a service then it means that the service's API is anemic - probably CRUD-based, designed as a thin wrapper over a database instead of an actual service.
A single "request" to a well-designed service should convey all of the information required to perform a single "unit of work" - in other words, those 10,000 requests could very likely be consolidated into one request, or at least a small handful of requests. This is especially important if requests are going to a remote server or may take a long time to complete (and 2-3 seconds is an extremely long time in computing).
If you do not have control over the service, if you do not have the ability to change the specification or the API - then I think you're going to find this very difficult. A single machine simply can't handle 10,000 outgoing connections at once; it will struggle with even a few hundred. You can try to parallelize this, but even if you achieve a tenfold increase in throughput, it's still going to take half an hour to complete, which is the kind of task you probably don't want running on a public-facing web site (but then, maybe you do, I don't know the specifics).
Perhaps you could be more specific about the environment, the architecture, and what it is you're trying to do?
In response to your update (possibly having thousands of users all performing an action at the same time that requires you to send one or two SMS messages for each):
This sounds like exactly the kind of scenario where you should be using Message Queuing. It's actually not too difficult to set up a solution using WCF. Some of the main reasons why one uses a message queue are:
There are a large number of messages to send;
The sending application cannot afford to send them synchronously or wait for any kind of response;
The messages must eventually be delivered.
And your requirements fit this like a glove. Since you're already on the Microsoft stack, I'd definitely recommend an asynchronous WCF service backed by MSMQ.
If you are working with SOAP, or some other type XML request, you may not have an issue dealing with the level of requests in a loop.
I set up something similar using a SOAP server with 4-5K requests with no problem...
A SOAP request to a web service (assuming .NET 2.0 and superior) looks something like this:
WebServiceProxyClient myclient = new WebServiceProxyClient();
myclient.SomeOperation(parameter1, parameter2);
myclient.Close();
I'm assuming that this code will will be embedded into your business logic that you will be trigger as part of the user initiated action, or as part of the scheduled task.
You don't need to do anything especial in your code to cope with a high volume of users. This will actually be a matter of scalling on your platform.
When you say 10.000 request, what do you mean? 10.000 request per second/minute/hour, this is your page hit per day, etc?
I'd also look into using an AsyncController, so that your site doesn't quickly become completely unusable.
I am working on a class library that retrieves information from a third-party web site. The web site being accessed will stop responding if too many requests are made within a set time period (~0.5 seconds).
The public methods of my library directly relate to a resource an file on the web server. In other words, each time a method is called, an HttpWebRequest is created and sent to the server. If all goes well, an XML file is returned to the caller. However, if this is the second web request in less than 0.5s, the request will timeout.
My dilemma lies in how I should handle request throttling (if at all). Obviously, I don't want the caller sit around waiting for a response -- especially if I'm completely certain that their request will timeout.
Would it make more sense for my library to queue and throttle the webrequests I create, or should my library simply throw an exception if the a client does not wait long enough between API calls?
The concept of a library is to give its client code as little to worry about as possible. Therefore I would make it the libraries job to queue requests and return results in a timely manner. In an ideal world you would use a callback or delegate model so that the client code can operate in asynchronously, not blocking the UI. You could also offer the option for skipping the queue, (and failing if it operates too soon) and possibly even offer priorities within the queue model.
I also believe it is the responsibility of the library author to default to being a good citizen, and for the library's default operation to be to comply to the conditions of the data provider.
I'd say both - you're dealing with two independent systems and both should take measures to defend themselves from excessive load. The web server should refuse incoming connections, and the client library should take steps to reduce the requests it makes to a slow or unresponsive external service. A common pattern for dealing with this on the client is 'circuit breaker' which wraps calls to an external service, and fails fast for a certain period after failure.
That's the Web server's responsibility, imo. Because the critical load depends on hardware, network bandwidth, etc a lot of things that are outside of your application's control, it should not concern itself with trying the deal with it. IIS can throttle traffic based on various configuration options.
What kind of client is it? Is this an interactive client, for eg: GUI based app?
In that case, you can equate that to a webbrowser scenario, and let the timeout surface to the caller. Also, if you know for sure that this webserver is throttling requests, you can tell the client that he has to wait for a given time period before retrying. In that way, the client will not keep on re-issuing requests, and will know when the first timeout occurs that it is futile to issue requests too fast.