Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design considerations for heavy loaded asp.net MVC + Web API application and asynchronous message bus

I'm planning to build a quite large application (large in term of concurrent user / number of request, not in term of features).

Basically, I'll have a service somewhere, that is waiting for commands execute them, and acknowledge the completion later. This service will use a service bus to communicate, making the execution eventual, before a acknowledge message is issued.

The consumers of this service can be any kind of application (WPF, SL, ...) but my main (and first) client will be an asp.net MVC application + WebApi (.Net 4.5) or MVC only (.Net 4.0) with ajax controller actions.

The web application will be relying on Ajax call to keep a user friendly responsive application.

I'm quite new to such full blown async architecture, and I'm having some questions to avoid future headache :

  • my web api calls can take some amount of times. How should I design properly the api to support long running operations (some kind of async?). I've read about the new async keyword, but for the sake of knowledge, I'd like to understand what's behind.
  • My calls to the service will consist is publishing a message and wait for the ack message. If I wrap this in a single method, how should I write this method? Should I "block" until the ack is received (I suppose I shouldn't)? Should I return a Task object and let the consumer decide?
  • I'm also wondering if SignalR can help me. With signalR, I think I can use a real "fire and forget" command issuing, and route up to the client to ack message.
  • Am I completely out of subject, and should I take another approach?

In term of implementation details / framework, I think I'll use :

  • Rabbitmq as messaging system
  • Masstransit to abstract the messaging system
  • asp.MVC 4 to build the UI
  • Webapi to isolate command issuing out of UI controllers, and to allow other kind of client to issue commands
like image 796
Steve B Avatar asked Oct 08 '22 03:10

Steve B


1 Answers

my web api calls can take some amount of times. How should I design properly the api to support long running operations (some kind of async?).

I'm not 100% sure where you're going. You ask questions about Async but also mention message queuing, by throwing in RabbitMQ and MassTransit. Message queuing is asynchronous by default.

You also mention executing commands. If you're referring to CQRS, you seperate commands and queries. But what I'm not 100% about is what you're referring to when mentioning "long running processes".

  • When you query data, the data should already be present. Preferably in a way that is needed for the question at hand.
  • When you query data, no long-running-process should be started
  • When you execute commands, a long-running-processes can be started. But that's why you should use message queuing. Specify a task to start the long running process, create a message for it, throw it onto the queue, forget about it altogether. Some other process in the background will pick it up.
  • When the command is executed, the long-running-process can be started.
  • When the command is executed, a database can be updated with data
  • This data can be used by the API if someone requests data

When using this model, it doesn't matter that the long-running-process might take up to 10 minutes to complete. I won't go into detail on actually having a single thread take up to 10 minutes to complete, including locks on database, but I hope you get the point. Your API will be free almost instantly after throwing a message onto the queue. No need for Async there.

My calls to the service will consist is publishing a message and wait for the ack message.

I don't get this. The .NET Framework and your queuing platform take care of this for you. Why would you wait on an ack?

In MassTransit

Bus.Instance.Publish(new YourMessage{Text = "Hi"});

In NServiceBus

Bus.Publish(new YourMessage{Text = "Hi"});

I'm also wondering if SignalR can help me.

I should think so! Because of the asynchronous nature of messaging, the user has to 'wait' for updates. If you can provide this data by 'pushing' updates via SignalR to the user, all the better.

Am I completely out of subject, and should I take another approach?

Perhaps, I'm still not sure where you're going. Perhaps read up on the following resources.

Resources:

http://www.udidahan.com/2013/04/28/queries-patterns-and-search-food-for-thought/ http://www.udidahan.com/2011/10/02/why-you-should-be-using-cqrs-almost-everywhere%E2%80%A6/ http://www.udidahan.com/2011/04/22/when-to-avoid-cqrs/ http://www.udidahan.com/2012/12/10/service-oriented-api-implementations/

http://bloggingabout.net/blogs/dennis/archive/2012/04/25/what-is-messaging.aspx http://bloggingabout.net/blogs/dennis/archive/2013/07/30/partitioning-data-through-events.aspx http://bloggingabout.net/blogs/dennis/archive/2013/01/04/databases-and-coupling.aspx

like image 196
Dennis van der Stelt Avatar answered Oct 12 '22 23:10

Dennis van der Stelt