private void RunJobs() { string xForwardedFor = HttpContext.Current.Request.Headers["X-Forwarded-For"]; string xForwardedProto = HttpContext.Current.Request.Headers["X-Forwarded-Proto"]; string xForwardedHost = HttpContext.Current.Request.Headers["X-Forwarded-Host"]; string appPath = !string.IsNullOrEmpty(xForwardedFor) && !string.IsNullOrEmpty(Config.ExtBasePath) ? Config.ExtBasePath : HttpContext.Current.Request.ApplicationPath; string http = ((Request.IsSecureConnection) ? "https" : "http") + (Request.Url.IsDefaultPort ? "://" : ":" + Request.Url.Port.ToString() + "//") + Request.Url.Host; string cronjobBaseUrl = !string.IsNullOrEmpty(Config.CronJobBaseUrl) ? Config.CronJobBaseUrl : (!string.IsNullOrEmpty(Config.IntBaseUrl) ? Config.IntBaseUrl : "" ); string baseUrl = !string.IsNullOrEmpty(cronjobBaseUrl) ? cronjobBaseUrl : http + (HttpRuntime.AppDomainAppVirtualPath == "/" ? "" : HttpRuntime.AppDomainAppVirtualPath) ; string myUrl = string.IsNullOrEmpty(cronjobBaseUrl) ? http + Request.Url.AbsolutePath : cronjobBaseUrl + "/CronJob.aspx"; Dictionary <string, string> requestInfo = GetRequestInfo(); Func <DateTime> currentTime = () => DateTime.Parse(DateTime.Now.ToUniversalTime().ToString("g")); // strip to minute for comparison. Action jobTask = () => { try { while (true) { lock (SystemList) { if (running) { return; } else { running = true; } } DateTime nextCheck = currentTime().AddMinutes(15); bool perMinute = false; List <string> jobsRun = new List <string>(); Dictionary <string, string> links = new Dictionary <string, string>(); DateTime now = currentTime(); string admEmail = base.SysAdminEmail(3); List <Tuple <Exception, Dictionary <string, string> > > errorList = new List <Tuple <Exception, Dictionary <string, string> > >(); bool singleSQLCredential = Config.DesShareCred; string RunCronJobModules = Config.RunCronJobModules; string dbDesDataBase; try { foreach (DataRow dr in SystemList.Rows) { if (dr["Active"].ToString() != "Y" || (!string.IsNullOrEmpty(RunCronJobModules) && !RunCronJobModules.Contains(dr["dbDesDatabase"].ToString())) ) { continue; } dbDesDataBase = dr["dbDesDatabase"].ToString(); string connStr = Config.GetConnStr(dr["dbAppProvider"].ToString(), dr["ServerName"].ToString(), dr["dbDesDatabase"].ToString(), "", dr["dbAppUserId"].ToString()); DataTable dtJobs = null; try { dtJobs = (new AdminSystem()).GetCronJob(null, string.Empty, connStr , singleSQLCredential ? Config.DesPassword : dr["dbAppPassword"].ToString()); } catch (Exception er) { string errorMsg = string.Format("Cronjob scan error {0}", dbDesDataBase); ErrorTrace(new Exception(errorMsg, er), "error", requestInfo); continue; } dtJobs.DefaultView.Sort = "NextRun, Year, Month, Day, Hour, Minute"; foreach (DataRowView drvJob in dtJobs.DefaultView) { now = currentTime(); string jobLink = drvJob["JobLink"].ToString(); if (drvJob["NextRun"].ToString() == "") { if (!links.ContainsKey(jobLink)) { //InvokeJob((int)drvJob["CronJobId"], dr["SystemId"].ToString(), jobLink, baseUrl); //jobsRun.Add(drvJob["JobLink"].ToString() + " first time on " + now.ToString()); //links.Add(jobLink, jobLink); try { base.UpdCronStatus((int)drvJob["CronJobId"], true, connStr , singleSQLCredential ? Config.DesPassword : dr["dbAppPassword"].ToString()); } catch (Exception ex) { try { string errorMsg = string.Format("Cronjob update status error for {0}({1})", jobLink, drvJob["CronJobId"].ToString()); ErrorTrace(new Exception(errorMsg, ex), "error", requestInfo); } catch { } //var d = new Dictionary<string,string>(){ // {"CronJobId", drvJob["CronJobId"].ToString()}, // {"JobLink", jobLink}, // {"Error",errorMsg}, //}; //errorList.Add(new Tuple<Exception, Dictionary<string, string>>(ex, d)); } } } else { DateTime nextRun = (DateTime)drvJob["NextRun"]; DateTime lastRun = (DateTime)drvJob["LastRun"]; if (nextRun <= now && nextRun.AddMinutes(1) > lastRun) { if (!links.ContainsKey(jobLink)) { InvokeJob((int)drvJob["CronJobId"], dr["SystemId"].ToString(), jobLink, baseUrl, requestInfo); jobsRun.Add(drvJob["JobLink"].ToString() + " intended on " + nextRun.ToString() + " UTC invoked on " + now.ToString() + " UTC"); links.Add(jobLink, jobLink); if (jobLink.ToLower().StartsWith("http")) { try { base.UpdCronStatus((int)drvJob["CronJobId"], connStr , singleSQLCredential ? Config.DesPassword : dr["dbAppPassword"].ToString()); } catch (Exception ex) { try { string errorMsg = string.Format("Cronjob update status error for {0}({1})", jobLink, drvJob["CronJobId"].ToString()); ErrorTrace(new Exception(errorMsg, ex), "error", requestInfo); } catch { } //var d = new Dictionary<string, string>(){ // {"CronJobId", drvJob["CronJobId"].ToString()}, // {"JobLink", jobLink}, // {"Error",string.Format("Cronjob update status error for {0}({1})", jobLink, drvJob["CronJobId"].ToString())}, //}; //errorList.Add(new Tuple<Exception, Dictionary<string, string>>(ex, d)); } } } //short? year = drvJob.Row.Field<short?>("Year"); //byte? month = drvJob.Row.Field<byte?>("Month"); //byte? day = drvJob.Row.Field<byte?>("Day"); //byte? hour = drvJob.Row.Field<byte?>("Hour"); //byte? min = drvJob.Row.Field<byte?>("Minute"); //byte? dow = drvJob.Row.Field<byte?>("DayOfWeek"); ////DateTime? next = RO.Common3.Utils.GetNextRun(year, month, day, dow, hour, min); //DateTime? next = GetNextRun(currentTime(), year, month, day, dow, hour, min); //(new AdminSystem()).UpdCronJob((int)drvJob["CronJobId"], DateTime.Now, next, connStr, dr["dbAppPassword"].ToString()); } else { if (nextRun < nextCheck) { nextCheck = nextRun; } break; } } } now = currentTime(); dtJobs.DefaultView.RowFilter = string.Format(@" (Year IS NULL OR Year = {0}) AND (Month IS NULL OR Month = {1}) AND (Day IS NULL OR Day = {2}) AND (DayOfWeek IS NULL OR DayOfWeek = {3}) AND (Hour IS NULL OR Hour = {4}) AND Minute IS NULL", now.Year, now.Month, now.Day, (int)now.DayOfWeek, now.Hour); if (dtJobs.DefaultView.Count > 0) { perMinute = true; } else { //dtJobs.DefaultView.RowFilter = ""; //DataRow drJob = dtJobs.DefaultView[0].Row; //short? year = drJob.Field<short?>("Year"); //byte? month = drJob.Field<byte?>("Month"); //byte? day = drJob.Field<byte?>("Day"); //byte? hour = drJob.Field<byte?>("Hour"); //byte? min = drJob.Field<byte?>("Minute"); //byte? dow = drJob.Field<byte?>("DayOfWeek"); ////DateTime? next = RO.Common3.Utils.GetNextRun(year, month, day, dow, hour, min); //DateTime? next = GetNextRun(DateTime.Now,year, month, day, dow, hour, min); //(new AdminSystem()).UpdCronJob((int)drJob["CronJobId"], DateTime.Now,next, connStr, dr["dbAppPassword"].ToString()); } } } catch (Exception er) { try { string errorMsg = string.Format("Cronjob invoke error"); ErrorTrace(new Exception(errorMsg, er), "error", requestInfo); } catch { } //var d = new Dictionary<string, string>(){ // {"CronJobId", null}, // {"JobLink", null}, // {"Error",string.Format("Cronjob invoke error {0} {1}", er.Message, er.StackTrace)}, // }; //errorList.Add(new Tuple<Exception, Dictionary<string, string>>(er, d)); } DateTime nextMin = currentTime().AddMinutes(2); if (jobsRun.Count > 0 && !string.IsNullOrEmpty(admEmail)) { RO.Common3.Data.Credential cr = new RO.Common3.Data.Credential("Anonymous", "Anonymous"); RO.Common3.Data.LoginUsr usr = (new LoginSystem()).GetLoginSecure(cr); string nonAnonymousWarning = usr == null ? "WARNING: This system does not have Anonymous Login" : ""; // Asynchronous send email for faster performance: Action a = () => { if (!summNotify) { summNotify = true; base.SendEmail("background job on " + myUrl.ToString(), "Summary (" + Application.GetHashCode().ToString() + "): Checked on " + DateTime.Now.ToUniversalTime().ToString() + " UTC; Next check on " + (perMinute ? nextMin : nextCheck).ToString() + " UTC <br/><br/>" + string.Join("<br/>", jobsRun.ToArray()) + "<br/><br/>" + nonAnonymousWarning, admEmail, admEmail, admEmail, "Admin", true); } }; a.BeginInvoke(null, null); } if (nextCheck > currentTime()) { if (perMinute) { if (currentTime() < nextMin) { Thread.Sleep(nextMin.Subtract(DateTime.Now.ToUniversalTime())); } } else { TimeSpan waitInterval = nextCheck.Subtract(DateTime.Now.ToUniversalTime()); Thread.Sleep(waitInterval); } } string myHash = Convert.ToBase64String(new System.Security.Cryptography.SHA256CryptoServiceProvider().ComputeHash(System.Text.UTF8Encoding.UTF8.GetBytes(Config.DesPassword))); WebRequest wr = HttpWebRequest.Create(myUrl + "?hash=" + HttpUtility.UrlEncode(myHash)); lock (SystemList) { running = false; } try { HttpWebResponse resp = (HttpWebResponse)wr.GetResponse(); if (((int)resp.StatusCode) <= 300) { // trumpline, i.e. we kill ourself and like the next invoke take over break; } } catch (Exception ex) { try { string errorMsg = string.Format("Cronjob refresh error {0}", myUrl); ErrorTrace(new Exception(errorMsg, ex), "error", requestInfo); } catch { } } } } catch (ThreadAbortException ex) { RO.Common3.Utils.NeverThrow(ex); } catch (Exception e) { try { string errorMsg = string.Format("Cronjob daemon error {0}", myUrl); ErrorTrace(new Exception(errorMsg, e), "error", requestInfo); } catch { } } finally { lock (SystemList) { running = false; } } }; jobTask.BeginInvoke(null, null); }
private void RunJobs() { string http = (Config.EnableSsl ? "https" : "http") + (Request.Url.IsDefaultPort ? "://" : ":" + Request.Url.Port.ToString() + "//") + Request.Url.Host; string baseUrl = http + HttpRuntime.AppDomainAppVirtualPath; string myUrl = http + Request.Url.AbsolutePath; Func <DateTime> currentTime = () => DateTime.Parse(DateTime.Now.ToUniversalTime().ToString("g")); // strip to minute for comparison. Action jobTask = () => { try { while (true) { lock (SystemList) { if (running) { return; } else { running = true; } } DateTime nextCheck = currentTime().AddMinutes(15); bool perMinute = false; List <string> jobsRun = new List <string>(); Dictionary <string, string> links = new Dictionary <string, string>(); DateTime now = currentTime(); string admEmail = base.SysAdminEmail(3); try { foreach (DataRow dr in SystemList.Rows) { string connStr = Config.GetConnStr(dr["dbAppProvider"].ToString(), dr["ServerName"].ToString(), dr["dbDesDatabase"].ToString(), "", dr["dbAppUserId"].ToString()); DataTable dtJobs = (new AdminSystem()).GetCronJob(null, string.Empty, connStr, dr["dbAppPassword"].ToString()); dtJobs.DefaultView.Sort = "NextRun, Year, Month, Day, Hour, Minute"; foreach (DataRowView drvJob in dtJobs.DefaultView) { now = currentTime(); string jobLink = drvJob["JobLink"].ToString(); if (drvJob["NextRun"].ToString() == "") { if (!links.ContainsKey(jobLink)) { //InvokeJob((int)drvJob["CronJobId"], dr["SystemId"].ToString(), jobLink, baseUrl); //jobsRun.Add(drvJob["JobLink"].ToString() + " first time on " + now.ToString()); //links.Add(jobLink, jobLink); try { base.UpdCronStatus((int)drvJob["CronJobId"], true, connStr, dr["dbAppPassword"].ToString()); } catch { } } } else { DateTime nextRun = (DateTime)drvJob["NextRun"]; DateTime lastRun = (DateTime)drvJob["LastRun"]; if (nextRun <= now && nextRun.AddMinutes(1) > lastRun) { if (!links.ContainsKey(jobLink)) { InvokeJob((int)drvJob["CronJobId"], dr["SystemId"].ToString(), jobLink, baseUrl); jobsRun.Add(drvJob["JobLink"].ToString() + " intended on " + nextRun.ToString() + " UTC invoked on " + now.ToString() + " UTC"); links.Add(jobLink, jobLink); if (jobLink.ToLower().StartsWith("http")) { try { base.UpdCronStatus((int)drvJob["CronJobId"], connStr, dr["dbAppPassword"].ToString()); } catch { } } } //short? year = drvJob.Row.Field<short?>("Year"); //byte? month = drvJob.Row.Field<byte?>("Month"); //byte? day = drvJob.Row.Field<byte?>("Day"); //byte? hour = drvJob.Row.Field<byte?>("Hour"); //byte? min = drvJob.Row.Field<byte?>("Minute"); //byte? dow = drvJob.Row.Field<byte?>("DayOfWeek"); ////DateTime? next = RO.Common3.Utils.GetNextRun(year, month, day, dow, hour, min); //DateTime? next = GetNextRun(currentTime(), year, month, day, dow, hour, min); //(new AdminSystem()).UpdCronJob((int)drvJob["CronJobId"], DateTime.Now, next, connStr, dr["dbAppPassword"].ToString()); } else { if (nextRun < nextCheck) { nextCheck = nextRun; } break; } } } now = currentTime(); dtJobs.DefaultView.RowFilter = string.Format(@" (Year IS NULL OR Year = {0}) AND (Month IS NULL OR Month = {1}) AND (Day IS NULL OR Day = {2}) AND (DayOfWeek IS NULL OR DayOfWeek = {3}) AND (Hour IS NULL OR Hour = {4}) AND Minute IS NULL", now.Year, now.Month, now.Day, (int)now.DayOfWeek, now.Hour); if (dtJobs.DefaultView.Count > 0) { perMinute = true; } else { //dtJobs.DefaultView.RowFilter = ""; //DataRow drJob = dtJobs.DefaultView[0].Row; //short? year = drJob.Field<short?>("Year"); //byte? month = drJob.Field<byte?>("Month"); //byte? day = drJob.Field<byte?>("Day"); //byte? hour = drJob.Field<byte?>("Hour"); //byte? min = drJob.Field<byte?>("Minute"); //byte? dow = drJob.Field<byte?>("DayOfWeek"); ////DateTime? next = RO.Common3.Utils.GetNextRun(year, month, day, dow, hour, min); //DateTime? next = GetNextRun(DateTime.Now,year, month, day, dow, hour, min); //(new AdminSystem()).UpdCronJob((int)drJob["CronJobId"], DateTime.Now,next, connStr, dr["dbAppPassword"].ToString()); } } } catch (Exception er) { } DateTime nextMin = currentTime().AddMinutes(2); if (jobsRun.Count > 0 && !string.IsNullOrEmpty(admEmail)) { RO.Common3.Data.Credential cr = new RO.Common3.Data.Credential("Anonymous", "Anonymous"); RO.Common3.Data.LoginUsr usr = (new LoginSystem()).GetLoginSecure(cr); string nonAnonymousWarning = usr == null ? "WARNING: This system does not have Anonymous Login" : ""; // Asynchronous send email for faster performance: Action a = () => { if (!summNotify) { summNotify = true; base.SendEmail("background job on " + myUrl.ToString(), "Summary (" + Application.GetHashCode().ToString() + "): Checked on " + DateTime.Now.ToUniversalTime().ToString() + " UTC; Next check on " + (perMinute ? nextMin : nextCheck).ToString() + " UTC <br/><br/>" + string.Join("<br/>", jobsRun.ToArray()) + "<br/><br/>" + nonAnonymousWarning, admEmail, admEmail, admEmail, "Admin", true); } }; a.BeginInvoke(null, null); } if (nextCheck > currentTime()) { if (perMinute) { if (currentTime() < nextMin) { Thread.Sleep(nextMin.Subtract(DateTime.Now.ToUniversalTime())); } } else { TimeSpan waitInterval = nextCheck.Subtract(DateTime.Now.ToUniversalTime()); Thread.Sleep(waitInterval); } } string myHash = Convert.ToBase64String(new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(System.Text.UTF8Encoding.UTF8.GetBytes(Config.DesPassword))); WebRequest wr = HttpWebRequest.Create(myUrl + "?hash=" + HttpUtility.UrlEncode(myHash)); lock (SystemList) { running = false; } try { HttpWebResponse resp = (HttpWebResponse)wr.GetResponse(); if (((int)resp.StatusCode) <= 300) { break; } } catch { } } } catch (Exception e) { } finally { lock (SystemList) { running = false; } } }; jobTask.BeginInvoke(null, null); }