I have a requirement where third party software running on a desktop will write to a local database and I need to send some of that information to a remote web service. I don't have any control over the thirdparty software that is doing the insert but I can read the database.
My approach is to have a windows service check the local table every second for an insert, if there is an insert send the webservice request. I don't like checking every second but this whole process needs to happen in a short amount of time after the insert. Is there a better way to go about this? Some kind of listener? I don't think I can use triggers.
This will be .NET and SQL Server if that matters.
Try using the SQLDependency class. Implement the onChange method of the class to handle your processing. The following article describes the process of configuring your environment and has some sample code for this.
http://www.codeproject.com/Articles/144344/Query-Notification-using-SqlDependency-and-SqlCach
Related
I am writing a ASP.NET ApiController that is hosted on IIS. In an action I need to invoke a Web Service named A provided by a company named Tencent. The service requires that I use a key to authenticate. The key is generate by calling another web interface, named B from Tencent and key is valid for 3 hours. Service B has a limitation on calls per day. Therefore I can't call B whenever I want to use A. I can only call B once and store the key in the database for future use.
That means every time I want to use Service A, I need to check the validation of key from database, and if it's expired, call B and get a new one.
Now, when I need to renew my key by calling B, what if before a new key is returned, the ApiController action is called again? The new request would also find that the key in database is stale, then goes on calling B again, invalidating A's newly gained key, causing A to fetch key again, endless loop.
My questions is, how do you get rid of this kind of worry? How do I start? From SQL or IIS or ASP.NET?
I am reading/writing database with EF6 and using ASP.NET MVC 5.
Thanks for your help!
-- Complement --
I was advised to use lock keyword. However I want to have a peace of mind knowing that lock will safe guard the database read/write piece across all IIS requests. So is there any article about how IIS handles multiple requests to the same ASP.NET module and concurrency control on that?
Use a lock around the code in question. The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released.
See https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
If it’s in a clustered environment they you will also need to create a transaction at the database level, which will check the last updated/expiry before performing an update.
I have a program in which it insert a raw in a table after certain operations. I wan to call a web service in code behind to do some special tasks by the using of info that there is in the inserted row.
How I can do that?
Is it good idea to invoke this web service from a stored procedure or not? What are the other options?
More Details: Actually, I have an operation in my web application that take a long time to be completed and it is seriously time consuming operation. I don't want client wait until this process finish. That is why I decide write a web service to do this process in the background.
Therefore, I think it may be a good idea that when client request receive I insert his request in a table and call a web service to handle it. Moreover, I do not want to wait until web service return the result, so I will aware client from its result through the report. I do not know what is the best solution to handle it.
I usually keep myself far away from table triggers(it sounds like you're about to use an on insert trigger for a table).
I don't know your specific situation but you could either :
Call the webservice before or after you call the stored procedure, this way the data layer(stored proc) only handles data and nothing more. You're logical layer will handle the logic of calling an extra webservice.
Write a service that will periodicly read a table and notify the webservice of the latest modifications. More messy but it resembles more the effect you're trying to achieve.
There are probably more solutions but i'd need more information on what it exactly is you're doing. Right now it's kinda vague :)
It is never a good idea to call webservice from Stored procs or other DB objects. You can call it from your code, just after you execute the insert and commit it.
The problem it sounds like is that you cannot guarantee that the web service will be called unless you call it before committing the transaction. However, it sounds like the web service needs to be called after commit. In this case, it sounds like you should use a message queue. You could either build one in your database or you could use one off the shelf (http://aws.amazon.com/sqs/ or http://www.windowsazure.com/en-us/home/features/messaging/).
The steps would be:
Insert message into queue (after this is success you can return the call, depending on what your contract with the caller is)
Read message
Insert into table
Call web service
Delete message
The downside is that you will need to make the operations (inserting into the table and calling the web service) idempotent.
I have been given a task where it should be possible for a user to pass some information to a database table.
The table should be seen as a queue.
My question is:
Is it possible to execute some code on the webserver asynchronously, so the users can use the website for others tasks meanwhile processing the queue?
Is it possible to use the Thread class and how ?
Look into Asynchronous Pages as a start - it is teh easiest way to do what you describe.
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx
You could use a service bus to get this done. If you feel up to it you could have a look at my open source esb:
http://shuttle.codeplex.com
It has an implementation that can use a sql table as a queue.
I have a web service that executes a task that may take hours to finish (asynchronously)
I would like to share the status of that task by all the clients that connects to the server (I'm using a web application for this)
For example, the first client that calls the page http://localhost/process.aspx
will instantiate the web service and it will call a method to start executing the task. A percentage number will be displayed showing the status of completion. I can do this by polling the web service using AJAX.
If there is another client that tries to opens that page, it should get the same percentage information so no new instances of the web service are created.
How is the best way of doing this?
I thought about different solutions but sooner or later I find new problems.
These are some of the possible alternatives:
Create an static object of the Web service.
Create the object in the global.asax file.
Do you guys have any other ideas? I'm not too familiar designing web sites and this is driving me crazy. I would appreciate if you guys could provide some code snippets.
Thanks
The issue is ensuring that the information pertaining to the single instance of a process is stored in exactly one place.
Your initial thinking can be applied, for instance, by using the Application object, but that will break down in a clustered IIS scenario.
I am not posative that a database is the absolute best solution, but I believe it would give you what you want.
If 100 clients try to start the process at the same time, only one can succeed, right? The databases locking facility will help you make that happen.
There's a method (I'm assuming WCF for the web service) that allows you to have exactly one instance of the service run... link
I think this is what you are trying to accomplish.
Assuming I have understood your requirements correctly. Your webservice should not be creating the instance of the “worker” object.
Your webservice request should log to either a database (as the other poster noted) or a messagequeue of somesort. At this point your “worker” processer (probably some type of service) should take over the job as it requires.
Basically you want to break up your application into something like this
| Webservice | ---------- | Datastore |-----------| Worker |
Any further requests regarding the batch should be managed by the webservice querying the datastore.
Remember webservices are NOT DESIGNED TO DO WORK.
Other than using a web service, is there anyway to call a method in a web app from a windows application? Both run on the same machine.
I basically want to schedule a job to run a windows app which updates some file (for a bayesian spam filter), then I want to notify the web app to reload that file.
I know this can be done in other ways but I'm curious to know whether it's possible anyway.
You can make your windows app connect to the web app and do a GET in a page that responds by reloading your file, I don't think it is strictly necessary to use a web service. This way you can also make it happen from a web browser.
A Web Service is the "right" way if you want them to communicate directly. However, I've found it easier in some situations to coordinate via database records. For example, my web app has bulk email capability. To make it work, the web app just leaves a database record behind specifying the email to be sent. The WinApp scans periodically for these records and, when it finds one with an "unprocessed" status, it takes the appropriate action. This works like a charm for me in a very high volume environment.
You cannot quite do this in the other direction only because web apps don't generally sit around in a timing loop (there are ways around this but they aren't worth the effort). Thus, you'll require some type of initiating action to let the web app know when to reload the file. To do this, you could use the following code to do a GET on a page:
WebRequest wrContent = WebRequest.Create("http://www.yourUrl.com/yourpage.aspx");
Stream objStream = wrContent.GetResponse().GetResponseStream();
// I don't think you'll need the stream Reader but I include it for completeness
StreamReader objStreamReader = new StreamReader(objStream);
You'll then reload the file in the PageLoad method whenever this page is opened.
How is the web application loading the file? If you were using a dependency on the Cache object, then simply updating the file will invalidate the Cache entry, causing your code to reload that entry when it is found to be null (or based on the "invalidated" event).
Otherwise, I don't know how you would notify the application to update the file.
An ASP.NET application only exists as an instance to serve a request. This is why web services are an easy way to handle this - the application has been instantiated to serve the service request. If you could be sure the instance existed and got a handle to it, you could use remoting. But without having a concrete handle to an instance of the application, you can't invoke the method directly.
There's plenty of other ways to communicate. You could use a database or some other kind of list which both applications poll and update periodically. There are plenty of asynchronous MQ solutions out there.
So you'll create a page in your webapp specifically for this purpose. Use a Get request and pass in a url parameter. Then in the page_load event check for this paremter. if it exists then do your processing. By passing in the parameter you'll prevent accidental page loads that will cause the file to be uploaded and processed when you don't want it to be.
From the windows app make the url Get request by using the .Net HttpWebRequest. Example here: http://www.codeproject.com/KB/webservices/HttpWebRequest_Response.aspx