How to handle long running web service operations? - soa

I have to create a Java EE application which converts large documents into different formats. Each conversion takes between 10 seconds and 2 minutes.
The SOAP requests will be made from a client application which I also have to create.
What's the best way to handle these long running requests? Clearly the process takes to much time to run without any feedback to the user.
I can think of the following ways to provide some kind of feedback, but I'm not sure if there isn't a better way, perhaps something standardized.
The client performs the request from a thread and the server sends the document in the response, which can take a few minutes. Until then the client shows a "Please wait" message, progress spinner, etc. (This seems to be simple to implement.)
The client sends a "Start conversion" command. The server returns some kind of job ID which the client can use to frequently poll for a status update or the final document. (This seems to be user friendly, because I can display a progress, but also requires the server to be stateful.)
The client sends a "Start conversion" command. The server somehow notifies the client when it is done. (Here I don't even know how to do this)
Are there other approaches? Which one is the best in terms of performance, stability, fault tolerance, user-friendliness, etc.?
Thank you for your answers.

Since this almost all done server-side, there isn't much a client can do besides poll the server somehow for updates on the status.
#1 is OK, but users get impatient really fast. "A few minutes" is a bit too long for most people. You'd need HTTP Streaming to implement #3, but I think that's overkill.
I would just go with #2.

For 3 the server should return a unique ID back to the client and using that ID the client has to ask the server the result at a later time

option 4 for those desiring to use web sockets
you request will be response with a jobId,
you get progress state over the web soket

Related

Can I intercept after a response has been sent to a client in an IHttpModule

I have a custom IHttpModule that is used to log all HTTP requests and responses, and this is currently working very well, but I'd love to extend it so I can determine how long a response actually takes.
The response is logged in the HttpApplication.EndRequest event, but this event fires before the request is actually sent to the web client. While this allows me to determine how long it took for the server to process the response, I'd also love to be able to time how long it actually took for the client to receive the response.
Is there an event, or some other mechanism, which will allow me to intercept after the client has finished receiving the response?
So that would require client-side code. But not entirely clear what you are wanting to measure. From smallest to largest, the timings could be
time inside server application - measured by code which you already have.
Your code can set the start from either the "Now()" when it begins, or using the HTTP objects. The first call to a site would see a big difference between these start times, otherwise they should be almost identical.
time on server website - I believe this is already measured by most hosting services like IIS.
server machine - I believe this is what "mo" is referring to. You would have to have some kind of external monitoring on the server machine, ala WireShark.
client machine - again, you would have to have some kind of external monitoring on the client machine. This would be the hardest to get, but I think is really what you are asking for.
client application - this is what you can measure with javascript.
Unless this is the "first call" (see Slow first page load on asp.net site or ASP.NET application on IIS7 - very slow startup after iisreset), I believe that all of these time will be just so close that you can use a "good enough" approach instead.
If you must have a measure of this call's client time, then you are stuck in a bad spot. But if you just want better numbers, just continue to measure 1. (application time) with what you already have, and make sure to also measure the size of the request and response.
Then set a base-line for adjusting that time, by testing on various target client machines.
Measure ping times from the client to your server
Measure transfer times of moderately large content - both upload and download
Finagle the numbers to get your average adjustment
You should end up with a formula like:
[AdjustedTime] = [PingTime] + [ServerTime]
+ ([UploadSpeed] * [RequestSize])
+ ([DownloadSpeed] * [ResponseSize]);
This would be the expected client response time.
yes you could handle HttpApplication.EndRequest
another way could be to hook (example: windows service to write response-time to a database) into your webserver (IIS) and trace those events.if you want to analyse the time, a client needs to get your content.
but i think, iis is already able todo so.
it depends a littlebit, what you want todo.

Queueing solutions for ASP.NET MVC

I looking into the concept of queueing for web apps (i.e. putting some types of job in a queue for completion by a seperate worker, rather than being completed in the web request cycle).
I would like to know if there are any good solutions existing for this which can be utilised in an ASP.NET MVC environemnt.
Has anyone had any (good or bad) experiences?
Thank you!
UPDATE:
Just to clarify, I'm not talking about queueing incoming requests. I'll try to illustrate what I mean...
1) Standard situation:
Request from browser
Server processing starts
Long job starts
Long job finished
Server processing finished
Response returned to browser
2) What I'm looking into:
Requsest from browser
Server processing starts
Long job placed in queue
Server processing finished
Response returned to browser
And in another process (possibly after the response was sent):
Long job taken from queue
Long job starts
Long job finished
In the first instance the user has waited a long time for server resoponse, in the second it was quick.
Of course there are certain types of jobs that would be appropriate for this, some that would not be.
UPDATE2:
The client doesn't have to be updated immediately with the results of the long job. The changes would just show themselves in the application whenever the user happened to refresh a page (after the job had completed of course).
Think of some of the things that happen in stack overflow - they are not immediately updated in each part of the application, but this happends quite quickly - I suspect some of these jobs are being queued.
Post the job data in an MSMQ queue and have a Windows Service process the items in the queue. Or, let the web request spawn a process that process the items in the queue.
The Rhino Service Bus is another solution that may work for you:
http://ayende.com/Blog/archive/2008/12/17/rhino-service-bus.aspx
You might check into using an ESB. I've played around with MassTransit: http://code.google.com/p/masstransit/ - the documentation is (or at least was) a little sparse, but it's easy to implement.
In addition, I develop apps for running on Amazon EC2 and absolutely love their AmazonSQS Service.
Thanks,
Hal
Since you mentioned in another comment that you were looking for an equivalent to amazon's sqs service ... you might want to look into Windows Azure. They have an equivalent queue api:
http://msdn.microsoft.com/en-us/library/dd179363.aspx
I have implemented this pattern by having the web server call a WCF service asynchronously. The VS wizards will generate async proxies for you when you consume a WCF service. If you must have guaranteed delivery on the request to the service, you could use MSMQ as the transport layer for the WCF service.
I think Chrisitan's comment might be your answer, but considering I don't know much about IIS and queueing with it, my solution would be:
Make an asynchronous request and load the job details in the database. Then have a job to loop through the database and process the job details. I do this for one of my sites. Might not be the best solution out there, but it gets the job done.
EDIT
My answer might still work, but you will need to have some polling mechanism on the client to continuously check the database to see if that user's job is done, then grab the data you need.

Multiple replies from server for one client request

This may be a dumb question - and the title may need to be improved... I think my requirement is pretty simple: I want to send a request for data from a client to a server program, and the server (not the client) should respond with something like "Received your request - working on it". The client then does other work. Then when the server has obtained the data, it should send an asynchronous message (a popup?) saying "I've got your data; click on ... (presumably a URL) to obtain data". I have been assuming that the server could be written in Java and that client is html and JavaScript. I haven't been able to come up with a clean solution - help would be appreciated.
Try to employ "Websocket Method" by using "SuperWebSocket" for server side, and "WebSocket4Net" for client side. It is working perfectly for my current project.
Most of the work invovles the server being asynchronous. To do this you must
Have an ajax call to the server that starts a job and returns a confirmation the job has been started.
A page on the server that will return whether or not any jobs are complete for a user.
Have an ajax widget on your client side that pings that page on teh server every so often to see if any jobs have been completed. And if so make a pop up.
This is the only way unless you use Flex data services.
Are you trying to do this on the HTTP protocol? It sounds like you're talking about a web application here, but it's not clear from the question. If so, then there are a variety of techniques for accomplishing this using AJAX which collectively go under the name "Comet". Depending on exactly what you're trying to accomplish, a number of different implementation, on both the client and server side, may be appropriate.
for pure java i suggest something like jgroups (client+server are java)
for html, you should use ajax - there you have a timer that checks every X seconds
Nowadays you have an alternative technique to use: Websockets. These are used for server->client communication without polling or ajax-style delayed responses.

asp.net website - should string manipulation happen on server or client?

I have a design question. I have a website where users enter short messages and they are displayed to other users. Sometimes these messages have formatting in them so I need to manipulate strings. I can do this either on the server or on the client. My question is where should it occur?
If it happens on the server then there's more of a load on the server as well as more data to push to the client. However, the server machine will usually be a "better" machine than what the users have.
If it happens on the client the string manipulation gets offset to the users but I'm not sure how efficient javascript/jquery string manipulation is.
Any thoughts on this?
I can't imagine a "short message" that would take so much string manipulation that a client machine would be noticeably inferior to a server. Put it on the client.
Well I am not sure how you are getting this string to the other users but I am assuming you sending it back to your server anyways so the question is, should you get it clean on the client and then send it to the server or just take whatever you get and clean it on the server.
If you can guarantee javascript is enabled then offloading it to the client would really cut down a lot of extra mini processes on the server with each call and distribute that load to the client which is great.
Things to consider... if you do it just in javascript you have no guarantee of what you are getting since you are not checking / cleaning the string on the server. This could be dangerous depending on how you are sending this information to other users. Just think of javascript injection attacks.
If you do it on the server then you don't really have to worry about it because you can guarantee what you are sending out is exactly what you want instead of just passing through whatever and hoping the javascript on the client has you covered.
Are you really doing so many transactions that the string manipulation is that much of a factor compared to whatever other operations you are doing with each message server side?
Depending on your definition of short (>1024 characters works for me) you would have to be turning through a LOT of them for there to be significant to your server.
That said...the fewer round trips you can make from your client to the server the better. Try to do it in JavaScript first. Then move it to the server if you have to.
I'd be tempted to keep it on the client side as much as possible. I might even go ahead and have client-side code compact / extract the messages as they arrive to save my web service or whatever is handing off the messages some bandwidth.

sending an email, but not now

I'm writing an application where the user will create an appointment, and instantly get an email confirming their appointment. I'd also like to send an email the day of their appointment, to remind them to actually show up.
I'm in ASP.NET (2.0) on MS SQL . The immediate email is no problem, but I'm not sure about the best way to address the reminder email. Basically, I can think of three approaches:
Set up a SQL job that runs every night, kicking off SQL emails to people that have appointments that day.
Somehow send the email with a "do not deliver before" flag, although this seems like something I might be inventing.
Write another application that runs at a certain time every night.
Am I missing something obvious? How can I accomplish this?
Choice #1 would be the best option, create a table of emails to send, and update the table as you send each email. It's also best not to delete the entry but mark it as sent, you never know when you'll have a problem oneday and want to resend out emails, I've seen this happen many times in similar setups.
One caution - tightly coupling the transmission of the initial email in the web application can result in a brittle architecture (e.g. SMTP server not available) - and lost messages.
You can introduce an abstraction layer via an MSMQ for both the initial and the reminder email - and have a service sweeping the queue on a scheduled basis. The initial message can be flagged with an attribute that means "SEND NOW" - the reminder message can be flagged as "SCHEDULED" - and the sweeper simply needs to send any messages that it finds that are of the "SEND NOW" or that are "SCHEDULED" and have a toBeSentDate >= the current date. Once the message is successfully sent - the unit of work can be concluded by deleting the message from the queue.
This approach ensures messages are not lost - and enables the distribution of load to off-peak hours by adjusting the service polling interval.
As Rob Williams points out - my suggestion of MSMQ is a bit of overkill for this specific question...but it is a viable approach to keep in mind when you start looking at problems of scale - and you want (or need) to minimize/reduce database read/write activity (esepcially during peak processing periods).
Hat tip to Rob.
For every larger project I usually also create a service which performs regular or periodical tasks.
The service updates its status and time of last execution somewhere in the database, so that the information is available for applications.
For example, the application posts commands to a command queue, and the service processes them at the schedule time.
I find this solution easier to handle than SQL Server Tasks or Jobs, since it's only a single service that you need to install, rather than ensuring all required Jobs are set up correctly.
Also, as the service is written in C#, I have a more powerful programming language (plus libraries) at hand than T-SQL.
If it's really pure T-SQL stuff that needs to be handled, there will be a Execute_Daily stored procedure that the service is going to call on date change.
Create a separate batch service, as others have suggested, but use it to send ALL of the emails.
The web app should record the need to send notifications in a database table, both for the immediate notice and for the reminder notice, with both records annotated with the desired send date/time.
Using MSMQ is overkill--you already have a database and a simple application. As the complexity grows, MSMQ or something similar might help with that complexity and scalability.
The service should periodically (every few minutes to a few hours) scan the database table for notifications (emails) to send in the near future, send them, and mark them as sent if successful. You could eventually leverage this to also send text messages (SMS) or instant messages (IMs), etc.
While you are at it, you should consider using the Command design pattern, and implement this service as a reusable Command executor. I have done this recently with a web application that needs to keep real estate listing (MLS) data synchronized with a third-party provider.
Your option 2 certainly seems like something you are inventing. I know that my mail system won't hold messages for future delivery if you were to send me something like that.
I don't think you're missing anything obvious. You will need something that runs the day of the appointment to send emails. Whether that might be better as a SQL job or as a separate application would be up to your application architecture.
I would recommend the first option, using either an SQL or other application to run automatically every day to send the e-mails. It's simple, and it works.
Microsoft Office has a delivery delay feature, but I think that is an Outlook thing rather than an Exchange/Mail Server thing, so you're going to have to go with option 1 or 3. Or option 4 would be to write a service. That way you won't have to worry about scheduled tasks to get the option 3 application to run.
If you are planning on having this app hosted at a cheap hosting service (like GoDaddy), then what I'd recommend is to spin off a worker thread in Global.asax at Application_Start and having it sleep, wake-up, send emails, sleep...
Because you won't be able to run something on the SQL Server machine, and you won't be able to install your own service.
I do this, and it works fine.

Resources