.Net: Threadify heavy API calls - c#

I have a email queue with email to be send. A webservice calls a SOAP webservice that processes the queue one by one.
We send email using an external vendor using their REST API. My problem is that calls to this API can take from 0.1ms to 12s. We sent thousands of emails to customer that subscribe to our notices and it important that in each batch there's not to much delay between the first compared to the last in the queue (ideally they'd be sent in simultaneously).
I've complained to the vendor but as they suck I'm quite sure they will not do anything about this.
Can I somehow Threadify this process, instantiating simultaneous calls to the server? The server is also my web server so I can't use all the juice. How many threads is appropriate? Is this a good idea? What's the best way to generically manage these threads?

You shouldn't be creating threads within an ASP.Net application. If you have a large enough queue to warrant multithreading you should create a windows service to handle the queue.

I would queue the email in a database table and generate a separate windows service that reads from the table and spawns a thread for each email, up to some max thread limit. The database can also be used to capture throughput time.
You also should find out how many simultaneous web service requests your vendor can handle. BCC yourself on the emails to find out if simultaneous submissions on your end end up as a single-threaded transmission on their end. And perhaps start shopping for an alternative to this vendor (you did say they suck).
If you want to get fancy and offload the effort from your own server, you send a batch of emails to a cloud service (Amazon Web Services, Microsoft Azure, or Google App Server) and spawn a process on the cloud to spray the emails to your vendor simultaneously.
You can also send the emails directly from the cloud, at least you can with Amazon. They provide a default limit, but then here's a link on how to remove the limit: http://aws.amazon.com/contact-us/ec2-email-limit-request/.

I have had some success with ThreadPool.QueueUserWorkItem() for a ASP.NET app. You can google for some usage examples.

There is no need to spawn threads yourself. The class generated by visual studio to access a web service already contains asynchronous methods. For each webservice call Foo, you will see that there is a BeginFoo and EndFoo method. The BeginFoo method will immediately return an IAsyncResult object while the webservice call is done in another thread.
See this MSDN topic for more information on how to use IAsyncResult.

Related

.Net prevent 2 parallel services processing the same command

I want to deploy an Windows services in parallel for redundancy and load balancing purposes.
How can i be sure that when the client sends a request to both of these services, that only 1 of them process the actual call?
Example:
When the client or other services sends a message to start a manufacturing process, both of these services will recieve that request. I want to make sure that only one of those services processes this request, so that manufacturing process do not get started twice!
Do they need to able to talk to themself?
Is there a possibility to sync those services?
Which is the most elegant/robust way of handling this problem?
Look into using a mutex to allow both services to only pick up a message once.
Mutex Description C#
Although, you'll need to make sure this can work in the way you want. this can help schedule between application processes and boundaries, but if this is deploy to two different machines, or Cloud services, the Mutex isn't going to work.
for that you'll need to figure out another of communicating across the applications, usually using a database or a MSMQ to create a message queue that you can pop messages off as you need them from each service.
The safest way, and also the best practice, for your example, would be to retrieve (not to peek) messages from a queue leveraging MSMQ. This gives you a clear explanation of the use case: https://learn.microsoft.com/en-us/previous-versions/windows/desktop/msmq/ms706253(v=vs.85)
~Pino

Threads/WebServices in Webserver

I'd like to know which is the best way to create a background task in the server, to send e-mails.
The idea is that a person bids an item, and this automatically sends a mail to the task responsible which it sends the mail to the correspondent person, but how can I do this without affecting the website functionality or making it slow.
I've read some things about async tasks but not sure if this is the solution to my problem.
You can create asynchronous background threads, look at the usage of
the .NET framework Task class if you are using .NET 4.x, in prior versions
you have to look at Thread or ThreadStart.
But be careful with accessing data, to prevent the main thread and your email
thread from getting into problems, you also need to look at locking resources
with the "lock" statement.
This is good, if you need to send many emails in one go and this should be done
asynchronously, which means "the user should not have to wait for it".
In the web, this is also the best way to do such things in a thread, as you
could get a request time out if it takes too long.
But of course, at the end of the thread, you should somehow create a report
and also send that to the executing user, so that he knows that mailing has finished
or if any errors occured.
We solved this in our company by creating a web service which is responsible
for shipping emails to the SMTP service and log them, including content and
status of email sending.
Our apllications build up the emails in the format defined from our web service
and they are responsible for staus report for the end user.
Of course by doing this, you will still need to have a layer which builds up
the email you want to send and the forward it to the mail service, and this
maybe still needs to be done async. so only the relaying to SMTP itself would
be separated from your application like this.
But if you have an application which needs to do mass mailing or something like that
and you want to separate it from your "normal" tool, (e.g. for separating processes
and process load) then simply create a separate service which "knows" the domain of your main application.
By doing this, you would only have to trigger the mailing service by sending the according information from the main application to the mailing service.
But again, maybe you need to build up a background thread which collects and sends the
information required to that service.
You could create this service in many ways, using WCF for example, as background windows service with message enqueing, or a HTTP based service with a rest API, etc. etc.
You did not give that much information about what you need to do, but maybe this will
point you to the right direction.

Use MSMQ queue to decouple message producer and consumer?

I would be grateful for some design suggestions concernig a windows service (c#) for publishing reports to a SOAP service.
It fetches a limited set of reports from a database (reports in Oracle AQ table), aggregates them into a message and forwards this message to a WCF SOAP service.
Reports are marked as "sent" if they have been transmitted via SOAP successfully.
Otherwise they are added again to the AQ table (via a db job).
So I came up with following designs.
What would be the best way to go?
Would the queue improve the design in terms of scalability, robustness, decoupling?
Is it a good idea to use queuing in this case?
Proposed design A:
Service with 1 to N threads.
Each thread processes reports synchronously (fetching reports, aggregating, translating, sending via SOAP)
Proposed design B:
Windows service with:
1 MSMQ message queue
1 to N Producer threads: (fetching reports,
aggregating, enqueuing message via MSMQ)
1 to N Consumer threads:
(dequeuing, translating, dipatching via SOAP)
Proposed design C:
Windows service with producer threads (fetching reports, aggregating, enqueuing messages to a private MSMQ queue via WCF NetMsmqBinding Client)
IIS/WAS hosted MSMQ-enabled service (listens to the MSMQ queue, dequeuing, translating, dipatching via SOAP)
Is there a particular reason you chose MSMQ? If you use your proposed design B, you could use BlockingCollection.
I don't see that MSMQ provides a particular advantage in this scenario unless you want multiple processes or you're expecting to spread this out across multiple computers.
But do you really even need multiple threads? It seems like your limiting factor here will be either database access time or communication to the WCF service. Unless the WCF service has to do some major processing before you can call the job successful.
So are you sure you can't just have:
while there are unsent jobs in the database
get job
send job to WCF
if job sent successfully
mark job as sent
end while
Obviously my knowledge of your situation is limited to what you've posted in your question, so it's possible I've missed something important.

making a web service faster (wcf)

We are trying to write an inner wcf service between 2 servers.
one off the application is a server application for our clients.
the clients sends us files and we then process them and converting them.
this whole process takes some time mean while the client session is open, i dont this using async is possible? which way can we make this methodology faster ?
keep in mind that we have aprox 1000 files an hour ...each client sends up to 200 files an hour also
G
You could to send an address to be called back when that file processing is done and it will notify the consumer server. Or to use a message queue on both ends.
This article (link) by Juval Lowy is all about one-way services, wcf call-back methods, etc. It should show you how to set your services up to handle what you're looking for.
One-way services make the call asynchronous - fire and forget. Setting up a call-back does what it sounds like - you can specify a service/method to be called back after a method executes.
Better yet, check out chapter 5 in Lowy's Programming WCF Services (link). It goes into MUCH greater detail than the article above.
I think the first link is enough to get started though.

Azure: Will it work for my App?

I'm creating an application that I want to put into the cloud. This application has one main function.
It hosts socket CLIENT sessions on behalf of other users (think of Beejive IM for the iPhone, where it hosts IM sessions for clients to maintain state on those IM networks, allowing the client to connect/disconnect at will, without breaking the IM network connection).
Now, the way I've planned it now, is that one 'worker instance' can likely only handle a finite number of client sessions (let's say 50,000 for argument sake). Those sessions will be very long lived worker tasks.
The issue I'm trying to get my head around is that I will sometimes need to perform tasks to specific client sessions (eg: If I need to disconnect a client session). With Azure, would I be able to queue up a smaller task that only the instance hosting that specific client session would be able to dequeue?
Right now I'm contemplating GoGrid as my provider, and I solve this issue by using Apache's Active Messaging Queue software. My web app enqueues 'disconnect' tasks that are assigned to a specific instance Id. Each client session is therefore assigned to a specific instance id. The instance then only dequeues 'disconnect' tasks that are assigned to it.
I'm wondering if it's feasible to do something similar on Azure, and how I would generally do it. I like the idea of not having to setup many different VM's to scale, but instead just deploying a single package. Also, it would be nice to make use of Azure's Queues instead of integrating a third party product such as Apache ActiveMQ, or even MSMQ.
I'd be very concerned about building a production application on Azure until the feature set, pricing, and licensing terms are finalized. For starters, you can't even do a cost comparison between it and e.g. GoGrid or EC2 or Mosso. So I don't see how it could possibly end up a front-runner. Also, we know that all of these systems will have glitches as they mature. Amazon's services are in much wider use than any of the others, and have been publicly available for much years. IMHO choosing Azure is a recipe for pain as they stabilize.
Have you considered Amazon's Simple Queue Service for queueing?
I think you can absolutely use Windows Azure for this. My recommendation would be to create a queue for each session you're tracking. Then enqueue the disconnect message (for example) on the queue for that session. The worker instance that's handling that connection should be the only one polling that queue, so it should handle performing the task on that connection.
Regarding the application hosting socket connections for clients to connect to, I'd double-check on what's allowed as I think only HTTP and HTTPS connections are allowed to be made with Azure.

Categories

Resources