ASP.NET sync long process w/ Requirements - asp.net

I am working with an e-commerce platform, and I have a task to synchronize with some remote accounting software. The task requires syncing orders, products, inventory...etc. With large amounts of data being synced,the process can take awhile. So, I don't think asp.net application would be the best place to handle this. So, the requirements are:
To be able to schedule this process to run overnight
To be able to manually fire off this process and pass into it some variables like order numbers to export.
Possibly get back status info when fired off manually.
Has to work on .net 3.5
Issues: Can't use a windows service because the site is hosted remotely on a shared service, and the host won't allow a service.
Ideas: I'm having a really hard time finding the best way to handle this outside asp.net that fits all requirements, but I do have access to their FTP and thought possibly a console app that hosts a web-service may work, and I can put Quartz scheduler in global file to fire off service from the site.
Anyway, please offer some thoughts and experiences if you have them on which methods have worked for you.

Can't use a windows service because the site is hosted remotely on a shared service, and the host won't allow a service.
That might be a problem. Does this hosting service provide any other kind of scheduling functionality? If not then you may need to consider changing your hosting services.
You're correct in that ASP.NET is not the tool you'd use for scheduling tasks. A web application is a request/response system (and is very much at the mercy of the hosting process, IIS usually for ASP.NET). So you need some way to schedule the task to execute at regular intervals. Windows Services, Windows Task Scheduler, or some other task scheduling tool.
As for the requirement to be able to invoke the process manually, that's a simple matter of separating the invocation of the logic from the logic itself. Picture the following components:
A module which performs the logic, not bound to any UI or any way of invoking it. Basically a Class Library project (or part of one).
A Windows Service or Console Application which references the Class Library and invokes the logic.
A Web Application which references the Class Library and invokes the logic.
Once you've sorted out how to schedule the Console Application, just schedule it and it's all set. If the process returns some information then the Console Application can also perform any notifications necessary to inform people of that information.
The Web Application can then also have an interface somewhere to invoke the process manually. Since the process "can take a while" then of course you won't want the interface to wait for it to complete. This can result in timeouts and leave the system in an unknown state. Instead you'd want to return the UI to the user indicating that the process has started (or been queued) and that they will be notified with the results when it completes. There are a couple of options for this...
You can use a BackgroundWorker to actually invoke the process. When the process completes, send a notification to the user who invoked it.
You can write a record to a database table to "queue" the process and have something like a Windows Service or scheduled Console Application (same scenario as above) which regularly polls that table for queued tasks, performs the task, and sends the notification. (Of course updating the status in the table along the way so it doesn't perform it twice.)
There are pros and cons either way, it's really up to you how you'd like to proceed. Ultimately you're looking at two main things here:
Separate the logic itself from the scheduling/invocation of the logic.
Utilize a scheduling system to schedule tasks. (If your hosting provider doesn't have one, find one that does.)

Related

Difference between web and desktop applications in database access

i have a bit theoretical question.
When creating web applications, there is difference to desktop applications with working and active connection to database. So im curious if there is some solution, which can provide more desktop-like access to database e.g. transactions on asynchronous requests from client (web browser)?
edit:
So i figured out, that there can be a transaction process of asynchronous request, from client. Is there solution, which can provide it in web apps?
e.g I have assynchronou ajax call, which consist of multiple operations, and i wana to process them as transaction. If everything is okay, operations will be all done. But if one of them fail, just rollback it. Like its in DB. Is it possible?
edit2: maybe im wrong and the issue is not about ajax, but about whole web applications, but i dont think there is a way how to make a asynchronnous request from web client.
Transaction need continuous connection to database. To make it work with web application you need a platform which allow the application to run continuously independent of client request. Java servlet is best fit, php is a no-no. So I asume you will use java servlet.
In java servlet, you can create a db transaction, create an id for it, and then store them in a static variable or in the provided application-wide object, context. Then, return the id to the client.
When the client want to send another request, make it send the id. The application then can locate the transaction variable based on the id. As long as the application doesn't restarted between the two requests, the transaction is still there and active.
Because web application don't know when the user leave the application, you must create a mechanism to check the transactions periodically, and then rollback it if the user leave them for a specified time period.
The database has no knowledge of who is connected outside of authentication.

choosing between a Windows service and a web app

We have an ASP.NET website where user adds items to database.
There are several sites on same server, each with its own database.
I need to implement a mechanism to check database for the state of each item.
If item is unprocessed, submit it to a third party web-service.
I see two options:
put the code in a webapp
put the code in a Windows service
The first option has the advantage that the code knows which database to connect to.
With Windows service, it has to be aware of all databases, so it's harder to maintain. Also, if I have only one Windows service, it will have to use threads to process items in each database in parallel.
Maybe there's another way beside these two?
What are the other issues, and what would you recommend?
Please explain your choice.
This sounds like a good place for a message queue to be involved. Each item would be wrapped into a message and placed in the queue. The "item processor" (a service?) would subscribe to the queue and perform some work using each item as it arrives. How the messages get placed on the queue is up to you, but for an example you could have each site publish the "new item" message to the queue.
Queues can be a bit of an intimidating concept at first, but frameworks such as MassTransit can help. Well worth learning.
I believe Windows Service is a good option compared to a web app, mainly because a web app would have to be triggered manually by someone, while a Windows Service can be running at all times, checking for updates.
There's another option, if you have access to each of the existing site's code. Why not write a Web Service that will submit data to your third party web service. Then in each of the existing web sites, modify the logic that stores changes in the database to also post the changes to your custom Web Service (or even skip the custom WS and call the third party directly).

Can an ASP.NET application handle NServiceBus events?

Most if not all of the NSB examples for ASP.NET (or MVC) have the web application sending a message using Bus.Send and possibly registering for a simple callback, which is essentially how I'm using it in my application.
What I'm wondering is if it's possible and/or makes any sense to handle messages in the same ASP.NET application.
The main reason I'm asking is caching. The process might go something like this:
User initiates a request from the web app.
Web app sends a message to a standalone app server, and logs the change in a local database.
On future page requests from the same user, the web app is aware of the change and lists it in a "pending" status.
A bunch of stuff happens on the back-end and eventually the requests gets approved or rejected. An event is published referencing the original request.
At this point, the web app should start displaying the most recent information.
Now, in a real web app, it's almost a sure thing that this pending request is going to be cached, quite possibly for a long period of time, because otherwise the app has to query the database for pending changes every time the user asks for the current info.
So when the request finally completes on the back-end - which might take a minute or a day - the web app needs, at a minimum, to invalidate this cache entry and do another DB lookup.
Now I realize that this can be managed with SqlDependency objects and so on, but let's assume that they aren't available - perhaps it's not a SQL Server back-end or perhaps the current-info query goes to a web service, whatever. The question is, how does the web app become aware of the change in status?
If it is possible to handle NServiceBus messages in an ASP.NET application, what is the context of the handler? In other words, the IoC container is going to have to inject a bunch of dependencies, but what is their scope? Does this all execute in the context of an HTTP request? Or does everything need to be static/singleton for the message handler?
Is there a better/recommended approach to this type of problem?
I've wondered the same thing myself - what's an appropriate level of coupling for a web app with the NServiceBus infrastructure? In my domain, I have a similar problem to solve involving the use of SignalR in place of a cache. Like you, I've not found a lot of documentation about this particular pattern. However, I think it's possible to reason through some of the implications of following it, then decide if it makes sense in your environment.
In short, I would say that I believe it is entirely possible to have a web application subscribe to NServiceBus events. I don't think there would be any technical roadblocks, though I have to confess I have not actually tried it - if you have the time, by all means give it a shot. I just get the strong feeling that if one starts needing to do this, then there is probably a better overall design waiting to be discovered. Here's why I think this is so:
A relevant question to ask relates to your cache implementation. If it's a distributed or centralized model (think SQL, MongoDB, Memcached, etc), then the approach that #Adam Fyles suggests sounds like a good idea. You wouldn't need to notify every web application - updating your cache can be done by a single NServiceBus endpoint that's not part of your web application. In other words, every instance of your web application and the "cache-update" endpoint would access the same shared cache. If your cache is in-process however, like Microsoft's Web Cache, then of course you are left with a much trickier problem to solve unless you can lean on Eventual Consistency as was suggested.
If your web app subscribes to a particular NServiceBus event, then it becomes necessary for you to have a unique input queue for each instance of your web app. Since it's best practice to consider scale-out of your web app using a load balancer, that means that you could end up with N queues and at least N subscriptions, which is more to worry about than a constant number of subscriptions. Again, not a technical roadblock, just something that would make me raise an eyebrow.
The David Boike article that was linked raises an interesting point about app pools and how their lifetimes might be uncertain. Also, if you have multiple app pools running simultaneously for the same application on a server (a common scenario), they will all be trying to read from the same message queue, and there's no good way to determine which one will actually handle the message. More of then than not, that will matter. Sending commands, in contrast, does not require an input queue according to this post by Udi Dahan. This is why I think one-way commands sent by web apps are much more commonly seen in practice.
There's a lot to be said for the Single Responsibility Principle here. In general, I would say that if you can delegate the "expertise" of sending and receiving messages to an NServiceBus Host as much as possible, your overall architecture will be cleaner and more manageable. Through experience, I've found that if I treat my web farm as a single entity, i.e. strip away all acknowledgement of individual web server identity, that I tend to have less to worry about. Having each web server be an endpoint on the bus kind of breaks that notion, because now "which server" comes up again in the form of message queues.
Does this help clarify things?
An endpoint(NSB) can be created to subscribe to the published event and update the cache. The event shouldn't be published until the actual update is made so you don't get out of sync. The web app would continue to pull data from the cache on the next request, or you can build in some kind of delay.

How do I implement Quartz.Net to schedule tasks for my MVC3 web app?

I'm building a project to send messages to users. The client wants a way to schedule these messages to be sent out at a certain time, for example, he creates the message at 2am but wants it to be sent out at 10am without his intervention, where do I begin with this sort of thing? I'm using ASP.NET MVC3, any help is appreciated.
Update
Darin has suggested Quartz.net, I've finally gotten around to attempting to set it up. But I'm not really understanding how to implement it with my web app.
I'm assuming I should be able to make an httprequest from my service to an action on my webapp, triggered by quartz. But I'm not sure how to communicate between the webapp and this service, such as sending instructions to the quartz server.
So far, I've created a windows service, set up the installers, and added the Quartz.net server 2010 solution to my service project, am I on the right track?
Using a managed Windows Service with Quartz.NET or a console application which you would schedule with the Windows task scheduler seems like a good approaches to achieve that.
Welp, there are scheduled tasks... either make a localhost request at a specific time, or write an executable/service to be called.
A possible alternative if you can't use scheduled tasks (but may be dependent upon the website being available to the Internet) is to make a remote request-maker program or use a website monitoring service. Have either of those make a request to a particular page/querystring on your site periodically. Then, make the web application perform a particular task (send an email) whenever that resource is requested.
A few free monitoring services are limited to one request every hour or half-hour, or you can pay to have it checked more often. The resource's code could be made to record the message-sending event, (thus making them only get sent once, regardless of how often the request is made)

Polling Long Running Windows Service from ASP.NET

We have an application that uses Lucene.NET within a windows service to reindex our app for search. Our admin section can trigger a full reindex in Lucene, and currently the only way to review its progress is through a log file written to disc.
This is clunky. We'd like to poll the service to determine the reindexing progress.
Does anyone have any insight into this?
Named pipes would be the way I would do cross process communication in this instance, if both processes would be running on the same machine.
If both processes are on different machines, it gets hairier and will probably involve something along the lines of a web service communicating with the process and then asp.net calling the web service.

Resources