Quartz.net durable and clustered - quartz.net

The config:
<quartz>
<add key="quartz.scheduler.instanceName" value="ChengongDemo" />
<add key="quartz.scheduler.instanceId" value="AUTO" />
<!--线程池-->
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="5" />
<add key="quartz.threadPool.threadPriority" value="Normal" />
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz" />
<add key="quartz.jobStore.dataSource" value="myDb" />
<add key="quartz.dataSource.myDb.connectionString" value="Data Source=192.168.15.23;Initial Catalog=Quartz;User ID=sa;Password=123456789" />
<add key="quartz.dataSource.myDb.provider" value="SqlServer-20" />
<!-- 集群-->
<add key="quartz.jobStore.Clustered" value="true" />
<add key="quartz.jobStore.clusterCheckinInterval" value="600" />
</quartz>
The code:
public static void Run()
{
ISchedulerFactory sf = new StdSchedulerFactory();
Sched = sf.GetScheduler();
var jobDetail = new JobKey("job1", "group1");
var triggerKey = new TriggerKey("trigger1", "group1");
if (!Sched.CheckExists(jobDetail) && !Sched.CheckExists(jobDetail))
{
var job = JobBuilder.Creaenter code herete<TestJob>()
.WithIdentity(jobDetail)
.Build();
var trigger = TriggerBuilder.Create()
.WithIdentity(triggerKey)
.ForJob(job.Key)
.WithCronSchedule("*/2 * * ? * *")
.Build();
Sched.ScheduleJob(job, trigger);
}
Sched.Start();
}
The Result:
enter image description here
The service run normally. I shundown for a few seconds,Then I start again.The
Job ran several times at the same time.
Why?Someone can help me?Thank you for your help.

If you want to disallow "running at the same time", then apply the
DisallowConcurrentExecution
attribute
https://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/more-about-jobs.html
As in
[DisallowConcurrentExecution]
public class MyDoesNotRunConcurrentlyJob : IJob
{
HOWEVER, I think what you are experiencing is your first experience with a "misire" , or a job didn't execute on the utopia schedule....then there are rules around that.
I would read the below URL. While its for the java-quartz (and quartz.net is a "port over" (to .net), the below is the best mini resource for understanding misfires.
he even mentions your specific case
"the scheduler itself was down"
http://www.nurkiewicz.com/2012/04/quartz-scheduler-misfire-instructions.html
I will copy the header information here, in case the url ever "dies", you (or more likely future readers) can use the below text to search for the article.
Quartz scheduler misfire instructions explained
Sometimes Quartz is not capable of running your job at the time when you desired. There are three reasons for that:
all worker threads were busy running other jobs (probably with higher priority)
the scheduler itself was down
the job was scheduled with start time in the past (probably a coding error)

Related

The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons)

I hosted my MVC website in plesk by using FTP publish option of VS2013 and everything went fine, I mean all the required files were copied properly in the destination under httpdocs virtual directory. But I am getting below error now when I visit the URL:
I have tried all the possible solutions mentioned in many links but no proper solution I have got so for! Its making me real confusing about this!
I have tried to apply solutions in this and also checked this question but none of them were useful. My web.config file is as below:
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=sometoken" requirePermission="false" />
</configSections>
<appSettings>
<!--<add key="MaintenanceMode" value="false" />-->
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="SessionTimeoutRedirect" value="true" />
<add key="isAjaxHandled" value="false" />
</appSettings>
<system.web>
<customErrors mode="Off" />
<trust level="Full"/>
<compilation targetFramework="4.0" defaultLanguage="c#"/>
<httpRuntime executionTimeout="1048576" maxRequestLength="100000" />
<globalization culture="en-IN" uiCulture="en-IN" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" defaultUrl="~/Admin/Index" timeout="2880" protection="Encryption" slidingExpiration="true" cookieless="AutoDetect" />
</authentication>
<pages controlRenderingCompatibilityVersion="4.0" />
</system.web>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings>
<add name="MCBConnectionString" connectionString="metadata=res://*/Models.EntityDataModel.MCBEntityModel.csdl|res://*/Models.EntityDataModel.MCBEntityModel.ssdl|res://*/Models.EntityDataModel.MCBEntityModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=somesource;Network Library=;Packet Size=4096;Integrated Security=no;User ID=uid;Password=pwd;Encrypt=yes;TrustServerCertificate=True; integrated security=no;connect timeout=120;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
</configuration>
Below is the file structure in Plesk Admin panel
One more thing to note: If I remove <trust level="Full"/> tag from web.config I will not get any error but no display too. A blank page will be shown
Am really confused about this! I am left with no other alternatives except to approach this forum now! Any experts out there who faced this issue or anything I have to configure more on web.config?
Place The below code
<compilation debug="true" targetFramework="4.0">
instead of
<compilation targetFramework="4.0" defaultLanguage="c#"/>
hope it's works
This Link actually helps you to identify any sort of issues if it is not displayed in the server and thus I [OP] was able to fix my problem by identifying the issue.
Below is what the link contains:
When using ASP.NET, you may encounter the following error: "Security
Exception" "Exception Details: System.Security.SecurityException:
Security error."
This means a class during runtime is linked against a restricted
class. By default ASP.NET error messages are optimized for
compile-time and run-time errors only. So the real error sources are
not displayed for linked errors. These errors arise for example, if
you try to access registry variables or system variables etc.
Sometimes you can get detailed error messages by placing the following
code in global.asax file.
<%# Application %>
<script runat="server" language="c#">
protected void Application_Error(Object sender, EventArgs e){
Exception ex = Server.GetLastError();
Server.ClearError();
Response.Write("<pre>");
Response.Write(Environment.NewLine);
Response.Write("Caught Exception: " + ex.ToString() + Environment.NewLine);
if (ex.InnerException != null){
Response.Write(Environment.NewLine);
Response.Write("Inner Exception: " + ex.InnerException.ToString() + Environment.NewLine);
Response.Write(Environment.NewLine);
}
System.Security.SecurityException ex_security = ex as System.Security.SecurityException;
if (ex_security != null){
Response.Write(Environment.NewLine);
Response.Write("Security Exception Details:");
Response.Write(Environment.NewLine);
Response.Write("===========================");
Response.Write(Environment.NewLine);
Response.Write("PermissionState: " + ex_security.PermissionState + Environment.NewLine);
Response.Write("PermissionType: " + ex_security.PermissionType + Environment.NewLine);
Response.Write("RefusedSet: " + ex_security.RefusedSet + Environment.NewLine);
}
Response.Write("</pre>");
}
</script>
If you are using asp.net mvc5, it needs full trust, which is not supported by plesk (host gator) at the moment I write this.
If that is the case you need to downgrade to mvc4 or find another hosting provider which supports full trust

How to specify the networkCredential param using xml in Serilog.Sinks.Email

I'm trying to setup this sink Serilog.Sinks.Email using xml
<add key="serilog:write-to:Email.restrictedToMinimumLevel" value="Warning" />
<add key="serilog:write-to:Email.from" value="email-from" />
<add key="serilog:write-to:Email.to" value="email-to" />
<add key="serilog:write-to:Email.mailServer" value="mail-server" />
<add key="serilog:write-to:Email.outputTemplate" value="tmpl" />
<add key="serilog:write-to:Email.networkCredential" value="???" />
since networkCredential implements ICredentialsByHost, is possible to specify it using xml?
This is a limitation in the config for the email sink, and/or appsettings support at the moment.

Umbraco Exmine engine return duplicate results after modifying a document

I'm using Examine to search in website content,
But whenever an article is updated, it is shown more than once in the result, with same count as the number of modifications !!
<IndexSet SetName ="ArabicIndexerIndexSet" IndexPath="~/App_Data/TEMP/ExamineIndexes/Arabic/">
<IndexUserFields>
<add Name="id" EnableSorting="true" Type="Number" />
<add Name="content" EnableSorting="true" />
<add Name="author" EnableSorting="true" />
<add Name="title" EnableSorting="true" />
<add Name="description" EnableSorting="true" />
<add Name ="umbracoNaviHide"/>
</IndexUserFields>
</IndexSet>
<ExamineSearchProviders defaultProvider="ArabicSearcher">
<providers>
<add name="ArabicSearcher" type="UmbracoExamine.UmbracoExamineSearcher, UmbracoExamine"
indexSet="ArabicIndexerIndexSet"
supportUnpublished="false"
supportProtected="false"
analyzer="Lucene.Net.Analysis.AR.ArabicAnalyzer, Lucene.Net.Contrib.Analyzers"/>
</providers>
</ExamineSearchProviders>
and this is my query:
+((title:Test Phrase content:Test Phrase)) +(umbracoNaviHide:0)
How to solve this?
EDIT:
Rebuilding the index solves the problem temporarily, and once you modify the article again, the problem appears again.
EDIT2:
I used Luke to investigate the problem, the only difference is the update date between the duplicated results.
See the image:
EDIT3:
I found a solution that worked, but I'm not convinced with it here: Index is not updated automatically
which suggests to use the follwing code:
public class UmbracoEvents: ApplicationBase
{
/// <summary>Constructor</summary>
public UmbracoEvents()
{
umbraco.content.AfterUpdateDocumentCache += new umbraco.content.DocumentCacheEventHandler(content_AfterUpdateDocumentCache);
}
privatevoid content_AfterUpdateDocumentCache(Document sender, umbraco.cms.businesslogic.DocumentCacheEventArgs e)
{
// Rebuild SiteSearchIndexer (Search results will be updated after a few minutes)
ExamineManager.Instance.IndexProviderCollection["SiteSearchIndexer"].RebuildIndex();
}
}
The problem with this solution is that it takes a long time to rebuild the index with large amount of content! (10000 documents in my case) and during the index rebuild process, the user will get 0 result searching anything, which confuses the user.
It looks like your search query is incorrectly structured. If you are searching for the phrase "Test Phrase" in the title and content property, your query should be:
+(title:Test Phrase content:Test Phrase) +(umbracoNaviHide:0)

Create job in code that persists the "quartz_jobs.xml" file

I have a quartz_jobs.xml file that has jobs defined in it.
I can load the quartz_jobs.xml file configuration and jobs start firing.
Aka, "reading" the jobs from the quartz_jobs.xml file works fine.
However, if I manually add a job to the IScheduler, this manually added job will start running......(along with jobs defined in the quartz_jobs.xml file)....
BUT the job is not ~written to the xml.
Is there a way to add a job to the IScheduler and have it write-back to the quartz_jobs.xml file?
Note, when I wired up the exact same code to a AdoStore, and I call the IScheduler.Start(), the jobs do get added to the database tables (aka, they persist).
But the same code wired to a RamStore running against Xml does not "save" the jobs to the quartz_jobs.xml file.
Thanks.
Here is my quartz.config (not the jobs) file.
<quartz>
<add key="quartz.plugin.jobInitializer.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin" />
<add key="quartz.scheduler.instanceName" value="DefaultQuartzScheduler" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="10" />
<add key="quartz.threadPool.threadPriority" value="2" />
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz" />
<add key="quartz.plugin.jobInitializer.fileNames" value="quartz_jobs.xml" />
<add key="quartz.plugin.jobInitializer.failOnFileNotFound" value="true" />
<add key="quartz.plugin.jobInitializer.scanInterval" value="120" />
</quartz>
http://quartznet.sourceforge.net/apidoc/2.0/html/html/2909678f-44c6-6e13-afa5-c50e7b5ee435.htm
XMLSchedulingDataProcessorPlugin Class Quartz.NET API Documentation
This plugin loads XML file(s) to add jobs and schedule them with triggers as the scheduler is initialized, and can optionally periodically scan the file for changes.
I don't think you can.
XMLSchedulingDataProcessor doesn't have any methods to serialize your jobs back to the file and QuartzXmlConfiguration20 seems to have only read-only collections.
I've tried to do some experiments.
Apparently you can manage to whole process of loading and processing the xml file:
ITypeLoadHelper loadHelper = new SimpleTypeLoadHelper();
loadHelper.Initialize();
XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(loadHelper);
processor.OverWriteExistingData = true;
processor.ProcessFileAndScheduleJobs("my_jobs.xml", Scheduler);
(so you do not have to use any configuration in your config file)
but, again, there's no way to append extra elements.
Another way could be to deserialize the xml file and try to manipulate it:
string xml = string.Empty;
using (var xmlJobFile = new System.IO.StreamReader("my_jobs.xml"))
{
xml = xmlJobFile.ReadToEnd();
}
XmlSerializer xs = new XmlSerializer(typeof(QuartzXmlConfiguration20));
QuartzXmlConfiguration20 data = (QuartzXmlConfiguration20)xs.Deserialize(new StringReader(xml));
if (data == null)
{
throw new SchedulerConfigException("Job definition data from XML was null after deserialization");
}
But it gets too complicated.
I reckon that the best option is to use AdoJobStore.

I can't seem to reference a class inside App_Code for model to get web config strings

I'm working on a project where we're trying to encapsulate all references of two databases on two different servers. We have this in a "utilities" file inside App_Code:
public static string myFirstDBName = System.Configuration.ConfigurationManager.AppSettings["firstDbName"];
public static string mySecondDBName = System.Configuration.ConfigurationManager.AppSettings["secondDbName"];
Which we can reference in any Controller no problem.
However, when I try to reference this in a model it doesn't see it - I tried a using statement and it didn't work. I'm hoping to pull this out of the model and put it in the same utilities file:
private readonly string _myFirstDBName = WebConfigurationManager.AppSettings["firstDBName"];
private readonly string _mySecondDBName = WebConfigurationManager.AppSettings["secondDBName"];
Can someone tell me if I'm missing anything? Or should we be putting this utilities file somewhere else? Thanks in advance!
Edit: Added my web.config values to correspond with this question:
<appSettings>
<add key="webpages:Version" value="1.0.0.0" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="firstDBName" value="db1" />
<add key="secondDBName" value="db2" />
</appSettings>
try web.Config
<configuration>
<connectionStrings>
<add name="DBName" connectionString="Data Source=(local);Initial Catalog=DBName;User ID=uid;Password=pwrd;" providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
you can also add app settings in web.Config
<appSettings>
<add key="KEY" value="VALUE" />
</appSettings>
update in regards to comment...
take this example
Model m = new Model();
m.prop = System.Configuration.ConfigurationManager.AppSettings["firstDBName"];
m.prop2 = System.Configuration.ConfigurationManager.AppSettings["secondDBName"];
return View("VIEWNAME", m);

Resources