Quartz.net and me don't seem to think the same way. Please help.
I'll have Quartz running as a Windows Service.
I'll have an Ado Jobstore setup on my SQL server.
I'll have the connection string setup that allows Quartz to access the jobstore.
I'll have a trigger job data map (stored in the jobstore?).
I see that I can set a Job-name, and can have Job Data Map key/value pairs that I can store for example a stored proc name and maybe a param. So far so good. I also see that I can write code that will implement iJob and in it grab the key/values from the context. My code could then call the stored proc with standard ADO code. I could do a similar thing with a webservice name and param, where my custom code would call the service.
Here are my questions:
1) Do I really have to create a separate piece of code to execute the stored proc or web service? I would think something as sophisticated as Quartz would be able to "natively" handle calls to stored procs, web services, maybe execute ftp commands, etc. Am I looking for a no-code solution when I shouldn't be?
2) Assuming I do have to write my own "do the work" code, where do I put that code? Do I compile into a DLL and place it somewhere? How do I tell Quartz where to look for my DLLs? And how do I associate the Job-Name in the config with my class in my DLL? Do I just use the Job-Name setting as the actual name of my class?
Thanks!
1) Yes, you still have to write separate job classes.
2) All your class has to do is implement the IJob interface and the scheduler will pick it up. Read the documentation.
Quartz is a scheduler, it's all it does and it does it well. It does not "natively" handle calls to stored procs, web services, or ftp commands. You have to write the code to do that in your class that implements IJob and is instantiated by Quartz on the schedule you specify.
The best thing to do is to create a separate class library (DLL) that you will reference from your app which creates an instance of Quartz scheduler and provide it with a fully qualified name of the class it needs to instantiate (e.g. MyLibrary.MyNameSpace.MyClass) and it will instantiate that class on the schedule and execute your code found in the overriden Execute() method of your class...
It's that simple...
Related
I have code that uses Entity Framework to treat data (retrieves data from multiple tables then performs operations on it before saving in a SQL database). The code was supposed to run when a button is clicked in an MVC web application that I created. But now the client wants the data treatment to run automatically every day at a set time (like an SSIS package). How do I go about this?
But now the client wants the data treatment to run automatically every day at a set time (like an SSIS package). How do I go about this?
In addition to adding a job scheduler to your MVC application as #Pac0 suggests, here are a couple of other options:
Leave the code in the MVC project and create an API endpoint that you can invoke on some sort of schedule. Give the client a PowerShell script that calls the API and let them take it from there.
Or
Refactor the code into a .DLL or copy/paste it into a console application that can be run on a schedule using the Windows Scheduler, SQL Agent or some other external scheduler.
You could use some tool/lib that does this for you. I could recommend Hangfire, it works fine (there are some others, I have not tried them).
The example on their homepage is pretty explicit :
RecurringJob.AddOrUpdate(
() => Console.WriteLine("Recurring!"),
Cron.Daily);
The above code needs to be executed once when your application has started up, and you're good to go. Just replace the lambda by a call to your method.
Adapt the time parameter on what you wish, or even better: make it configurable, because we know customers like to change their mind.
Hangfire needs to create its own database, usually it will stay pretty small for this kind of things. You can also monitor if the jobs ran well or not, and check no the hangfire server some useful stats.
I can't seem to find anything related to this problem. So I have a web-app I'm building using AngularJS and the others (html,etc) for UI, which connects with an Entity Framework in Asp.net (Either API or MVC, I'm not sure) for rest calls. That then connects to a sql database for model retrieval.
I have a SQLCMD which executes a stored procedure and creates a new time-stamped file of records from the database. The idea is that users will be able to click a button in the interface and a file will be generated without anyone ever having to touch sqlserver that they cna then put into excel. This has lead me on a search of topics like "WebMethods to call sqlcmd", "Calling .net webmethods with Angularjs", and "executing stored procedures with ASP.net", but nothing seems to be similar to what I'm asking (which leads me to believe maybe I don't have the best idea and it can be done better).
Any ideas? Just some pointers on where I should start or how I can tackle the problem would be greatly appreciated. I don't even have to return anything, it just needs to execute so this file can be created.
Your problem has nothing to do with AngularJS.
AngularJS is just some client side code that will eventually call MVC or WebApi code (as you state).
Your problem is .. having server side dotnet code call an external .exe.
http://dotnetslackers.com/community/blogs/haissam/archive/2007/02/02/Run-Executable-file-in-ASP.NET.aspx
// Create An instance of the Process class responsible for starting the newly process.
System.Diagnostics.Process process1 = new System.Diagnostics.Process();
// Set the directory where the file resides
process1.StartInfo.WorkingDirectory = Request.MapPath("~/");
// Set the filename name of the file you want to open
process1.StartInfo.FileName = Request.MapPath("WindowsMediaPlayer.exe");
// Start the process
process1.Start();
You just need to get familiar with System.Diagnostics.Process.
One big gotcha will be permissions (that is running the IIS) being able to run sqlcmd.exe.
I ended up doing a completely different idea and exported directly from Angular, Export to xls using angularjs, and did'nt worry about .NET or SQL for it.
This was way simpler and is better for me since the user can actually select what they want to export rather than just a total database dump.
I have business logic coded in Groovy and stored in a database table. I would love to edit this code inside Intellij IDEA with all the code completion possibilities etc. provided by this great IDE.
I could copy the script from the database table into a temporary file; edit it and store it back into the database. I could also write a plugin. But is there maybe already a way to do this with IDEA?
As I know, you can create "External tool", calling a simple import/export script, that will allow you to automate some tasks, you'd like.
Writing plugin isn't very simple task, and is an overhead as I think.
Also, you can use some wrapper inside your application, to work with debug configuration, when buisness logic scripts are loaded directly from files. It will also allow you to autoreload them, using groovy integration features. GroovyScriptEngine
Still trying to wrap my head around Quartz.NET after reading all the tutorials, which seem very code specific, versus implementation focused. Here's what I'm trying to do. I have 20 SQL stored procs that do various things, like query log tables, resubmit data to other processes, etc. I'd like to have these SP running throughout the day at regular intervals. So it seems like a natural for Quartz.NET. I plan on creating a Windows Svc that implements Quartz.NET and contains jobs in assemblies in the same folder as the Quartz assembly.
One bad way to implement this, I think, would be to write a single job class for every SP and associate a separate trigger for each one. The job class would simply execute a particular SP whose named was hard coded in the class. That's the bad way.
But for the life of me I can't figure out what the Good way would be. Obviously having a single job class that just does a generic 'execute SP by name', where the names come from a simple SQL table, seems like the way to go, but how would I get different triggers associated with different SPs, and how would Quartz know to load up all twenty SPs on separate threads?
And how would Quartz know to pickup a changed trigger for example for one of the SPs? Would that have to be a start/stop cycle on the Win Svc to reload jobs and triggers, or would I have to hand code some kind of "reload" too?
Any thoughts? Am I misunderstanding what Quartz is? The verbiage makes it sound like it's an Enterprise Scheduler, a System, a thing you install. All the documentation OTOH makes it seem like just a bunch of classes you stitch together to create your OWN scheduler or scheduling system, no different from the classes MS provides in .NET to create apps that do FTP for example. Maybe I'm expecting too much?
A pretty easy way to fulfill your requirements could be:
Start with sample server
Take Quartz.NET distribution's server as starting point, you have there a ready made template for a Windows service that utilizes TopShelf for easy installation
Use XML configuration with change detection
quartz.config file contains the actual configuration, there you can see that jobs and triggers are read from XML file quartz_jobs.xml .
You need to add quartz.plugin.xml.scanInterval = 10 to watch for changes (every ten seconds)
Use trigger job data maps to parameterize the job
You can use same job class for every trigger if SQL execution is as trivial as you propose. Just add needed configuration to trigger's definition in XML (sample here that runs every ten seconds, add as many triggers as you want):
<trigger>
<simple>
<name>sqlTrigger1</name>
<job-name>genericSqlJob</job-name>
<job-group>sqlJobs</job-group>
<job-data-map>
<entry>
<key>sql_to_run</key>
<value>select 1</value>
</entry>
</job-data-map>
<misfire-instruction>SmartPolicy</misfire-instruction>
<repeat-count>-1</repeat-count>
<repeat-interval>10000</repeat-interval>
</simple>
</trigger>
Just use the quartz_jobs.xml as base and make required changes.
Use configuration in your job
You can access the configuration in your job from context's MergedJobDataMap that contains both job's and trigger's parameters, latter overriding former.
public void Execute(IJobExecutionContext context)
{
string sqlToRun = context.MergedJobDataMap.GetString("sql_to_run");
SqlTemplate.ExecuteSql(sqlToRun);
}
So, I don't know if the question is explicit enough, but here's my problem:
I am writing a small application in VB.Net, that retrieves information from a website and present it to the user. Basically, I have written a class, which has a Get(URL) method which retrieves the webpage, reads it and populates the various Properties (Read-only) of the object.
This class works OK.
Now, I would like to store that information in a Database (I'm using Access for now), so that I can read the data from the DB, if the class gets called for a known URL. As I'm fairly new to OOP and completely new to DB usage in desktop applications (no problems in designing the DB though), I am not sure on how to proceed:
Should I put the database code in my existing class?
Should I create an extended class based on the existing one, adding the DB code?
Should I create a completely different class for the DB data and put the switch logic (read from DB or from web) in my application?
...
I realize that my question may sound silly to the most experienced of you, but I'm new to this and I would really like to learn how to do things the right way the first time!!!
Thanks!
This is what I would do:
Create a new class for the database code, and create an
interface for it that it implements.
Then create another class that has the code to fetch the web data. Make it implement the same interface.
Now you can subsitute either class to do your data access from your controller class.
Also, I usually put database and data access in separate projects from my service and ui classes, which are in their own classes, but that might be overkill for your situation.
If you'd like to read more on the subject, look up n-tier application design. The tier you're talking about here is data access.
http://en.wikipedia.org/wiki/Data_access_layer