Commit 0221e022f5bf1a564df833e7bb8dcf1bc5d23c63
1 parent
88b98a18
Vrh.Web.Reporting v1.1.0.0
Vrh.iScheduler v3.3.0.0
Showing
6 changed files
with
399 additions
and
191 deletions
Show diff stats
Vrh.Web.Reporting/Global.asax.cs
... | ... | @@ -16,20 +16,23 @@ using Hangfire; |
16 | 16 | using Microsoft.Web.Administration; |
17 | 17 | using Vrh.iScheduler; |
18 | 18 | using Vrh.Logger; |
19 | -using Vrh.Web.HangfireBootstrapperNS; | |
19 | +using Vrh.Web.WebServerHostedServiceStarterNS; | |
20 | 20 | namespace Vrh.Web.Reporting |
21 | 21 | { |
22 | 22 | public class MvcApplication : System.Web.HttpApplication |
23 | 23 | { |
24 | 24 | protected void Application_Start() |
25 | 25 | { |
26 | + Thread.Sleep(20000); | |
26 | 27 | (new DCLogEntry(LogLevel.Information, $"{typeof(MvcApplication).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}")).Write(); |
27 | 28 | AreaRegistration.RegisterAllAreas(); |
28 | 29 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); |
29 | 30 | RouteConfig.RegisterRoutes(RouteTable.Routes); |
30 | 31 | BundleConfig.RegisterBundles(BundleTable.Bundles); |
31 | 32 | |
32 | - HangfireBootstrapper.Init(Vrh.iScheduler.Monitor.InitHangfire); | |
33 | + WebServerHostedServiceStarter.Init(typeof(Vrh.iScheduler.WAHostedMonitorHangfire)); | |
34 | + //IISHostedServiceStarter.Init(Vrh.iScheduler.WAHostedMonitorHangfire.Start, Vrh.iScheduler.WAHostedMonitorHangfire.Stop); | |
35 | + //IISHostedServiceStarter.Init(Vrh.iScheduler.WAHostedMonitor.Start, Vrh.iScheduler.WAHostedMonitor.Stop); | |
33 | 36 | |
34 | 37 | //Vrh.Web.Menu inicializáló beállításai |
35 | 38 | Vrh.Web.Menu.Global.CustomerLogo = "~/Content/Images/Menu_LearLogo.jpg"; |
... | ... | @@ -39,7 +42,7 @@ namespace Vrh.Web.Reporting |
39 | 42 | protected void Application_End(object sender, EventArgs e) |
40 | 43 | { |
41 | 44 | (new DCLogEntry(LogLevel.Information, $"{typeof(MvcApplication).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}")).Write(); |
42 | - HangfireBootstrapper.Stop(); | |
45 | + WebServerHostedServiceStarter.Stop(); | |
43 | 46 | } |
44 | 47 | /// <summary> |
45 | 48 | /// Ha "Internal Server Error 500" üzenetet kapsz, akkor ide érdemes a hívás előtt betenni egy break point-ot. | ... | ... |
Vrh.Web.Reporting/Properties/AssemblyInfo.cs
... | ... | @@ -36,6 +36,6 @@ using System.Runtime.InteropServices; |
36 | 36 | // You can specify all the values or you can default the Build and Revision Numbers |
37 | 37 | // by using the '*' as shown below: |
38 | 38 | // [assembly: AssemblyVersion("1.0.*")] |
39 | -[assembly: AssemblyVersion("1.0.0.0")] | |
40 | -[assembly: AssemblyFileVersion("1.0.0.0")] | |
41 | -[assembly: AssemblyInformationalVersion("1.0.0")] | |
39 | +[assembly: AssemblyVersion("1.1.0.0")] | |
40 | +[assembly: AssemblyFileVersion("1.1.0.0")] | |
41 | +[assembly: AssemblyInformationalVersion("1.1.0")] | ... | ... |
Vrh.Web.Reporting/Vrh.Web.Reporting.csproj
... | ... | @@ -344,7 +344,7 @@ |
344 | 344 | <Compile Include="Global.asax.cs"> |
345 | 345 | <DependentUpon>Global.asax</DependentUpon> |
346 | 346 | </Compile> |
347 | - <Compile Include="HangfireBootstrapper.cs" /> | |
347 | + <Compile Include="WebServerHostedServiceStarter.cs" /> | |
348 | 348 | <Compile Include="Properties\AssemblyInfo.cs" /> |
349 | 349 | </ItemGroup> |
350 | 350 | <ItemGroup> | ... | ... |
Vrh.Web.Reporting/HangfireBootstrapper.cs renamed to Vrh.Web.Reporting/WebServerHostedServiceStarter.cs
... | ... | @@ -17,68 +17,130 @@ using Hangfire; |
17 | 17 | using Microsoft.Web.Administration; |
18 | 18 | using Vrh.Logger; |
19 | 19 | using System.Configuration; |
20 | +using System.Reflection; | |
20 | 21 | |
21 | -namespace Vrh.Web.HangfireBootstrapperNS | |
22 | +namespace Vrh.Web.WebServerHostedServiceStarterNS | |
22 | 23 | { |
23 | - public class HangfireBootstrapper : IRegisteredObject, IProcessHostPreloadClient | |
24 | + /// <summary> | |
25 | + /// TODO: ezt egy olyan helyre kellene rakni, ahol mindenhova referálható (az Vrh.Interfaces.dll egyre jobb ötletnek tűnik! Kár hogy nem hallgattam Antira!) | |
26 | + /// </summary> | |
27 | + public interface IWebServerHostedServiceStarter | |
28 | + { | |
29 | + void Start(); | |
30 | + void Stop(); | |
31 | + } | |
32 | + public class WebServerHostedServiceStarter : IRegisteredObject, IProcessHostPreloadClient | |
24 | 33 | { |
25 | 34 | /// <summary> |
26 | - /// Egy külső iniciátort hregisztrálására szolgál, amelyben lehetőség van a | |
27 | - /// paraméterként megkapott BackgroundJobServer-re ütemezett feladatokat definiálni. | |
35 | + /// Egy hosted service elindítását, paraméterezését, konfigurálását és a külső iniciátor meghívást végzi. | |
28 | 36 | /// </summary> |
29 | - public static void InitConfig(Action<object> externalinitializer=null) | |
37 | + /// <param name="tt"> | |
38 | + /// az indító és leállító metódusokat tartalmazó osztály; | |
39 | + /// IWebServerHostedServiceStarter interfészt meg kell valósítsa, bár ezt nem ellenőrzi, csak azt, | |
40 | + /// hogy az ezt jelentő 'public static void Start();' és 'public static void Stop();' metódusok megvannak-e. | |
41 | + /// </param> | |
42 | + public static void Init(Type tt) | |
30 | 43 | { |
31 | - if (externalinitializer == null) return; | |
32 | - var le = new DCLogEntry(LogLevel.Information, $"{typeof(HangfireBootstrapper).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); | |
33 | - try { _InitConfig(externalinitializer, le); } | |
34 | - catch (Exception ex) { le.AddExceptionResult(ex);le.SetLogLevel(LogLevel.Error); } | |
44 | + var le = new DCLogEntry(LogLevel.Information, $"{typeof(WebServerHostedServiceStarter).FullName}.{nameof(Init)}"); | |
45 | + try | |
46 | + { | |
47 | + //if (!tt.GetInterfaces().Contains(typeof(IWebServerHostedServiceStarter))) throw new InterfaceErrorApplicationException(tt.FullName); | |
48 | + | |
49 | + _SetupAutoStart<WebServerHostedServiceStarter>(le: le); | |
50 | + | |
51 | + var startmethod = tt.GetMethod(nameof(IWebServerHostedServiceStarter .Start), BindingFlags.Public | BindingFlags.Static); | |
52 | + var stopmethod = tt.GetMethod(nameof(IWebServerHostedServiceStarter .Stop), BindingFlags.Public | BindingFlags.Static); | |
53 | + if (startmethod == null || startmethod.ReturnType != typeof(void) || startmethod.GetParameters().Count() > 0) throw new InterfaceErrorApplicationException(tt.FullName,nameof(IWebServerHostedServiceStarter .Start)); | |
54 | + if (stopmethod == null || stopmethod.ReturnType != typeof(void) || stopmethod.GetParameters().Count() > 0) throw new InterfaceErrorApplicationException(tt.FullName, nameof(IWebServerHostedServiceStarter .Stop)); | |
55 | + IISHostedServiceStarterInstance._RegisterExternalInitializer((Action)Delegate.CreateDelegate(typeof(Action), startmethod), (Action)Delegate.CreateDelegate(typeof(Action), stopmethod), le); | |
56 | + | |
57 | + IISHostedServiceStarterInstance._StartExternalInitializers(le); | |
58 | + } | |
59 | + catch (InterfaceErrorApplicationException ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } | |
60 | + catch (Exception ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } | |
35 | 61 | finally { le.Write(); } |
36 | 62 | } |
37 | - private static void _InitConfig(Action<object> externalinitializer, DCLogEntry le) | |
63 | + | |
64 | + /// <summary> | |
65 | + /// Egy hosted service elindítását, paraméterezését, konfigurálását és külső iniciátorok meghívást végzi. | |
66 | + /// </summary> | |
67 | + /// <param name="externalinitializerstartmethod">az indító metódus</param> | |
68 | + /// <param name="externalinitializerstopmethod">a leállító metódus</param> | |
69 | + public static void Init(List<Type> ttList) | |
38 | 70 | { |
39 | - if (externalinitializer != null) | |
71 | + var le = new DCLogEntry(LogLevel.Information, $"{typeof(WebServerHostedServiceStarter).FullName}.{nameof(Init)}"); | |
72 | + try | |
40 | 73 | { |
41 | - externalinitializerList.Add(externalinitializer); | |
42 | - le.AddDataField("ADD external initializer", $"{externalinitializer.Method.DeclaringType.FullName}.{externalinitializer.Method.Name}()"); | |
74 | + //if (!tt.GetInterfaces().Contains(typeof(IInterface))) throw new Exception ($"{tt.FullName} does not implement {nameof(IInterface)}!"); | |
75 | + | |
76 | + _SetupAutoStart<WebServerHostedServiceStarter>(le: le); | |
77 | + foreach (var tt in ttList) | |
78 | + { | |
79 | + try | |
80 | + { | |
81 | + var startmethod = tt.GetMethod(nameof(IWebServerHostedServiceStarter .Start), BindingFlags.Public | BindingFlags.Static); | |
82 | + var stopmethod = tt.GetMethod(nameof(IWebServerHostedServiceStarter .Stop), BindingFlags.Public | BindingFlags.Static); | |
83 | + if (startmethod == null || startmethod.ReturnType != typeof(void) || startmethod.GetParameters().Count() > 0) throw new InterfaceErrorApplicationException(tt.FullName, nameof(IWebServerHostedServiceStarter .Start)); | |
84 | + if (stopmethod == null || stopmethod.ReturnType != typeof(void) || stopmethod.GetParameters().Count() > 0) throw new InterfaceErrorApplicationException(tt.FullName, nameof(IWebServerHostedServiceStarter .Stop)); | |
85 | + IISHostedServiceStarterInstance._RegisterExternalInitializer((Action)Delegate.CreateDelegate(typeof(Action), startmethod), (Action)Delegate.CreateDelegate(typeof(Action), stopmethod), le); | |
86 | + } | |
87 | + catch (InterfaceErrorApplicationException ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } | |
88 | + } | |
89 | + IISHostedServiceStarterInstance._StartExternalInitializers(le); | |
43 | 90 | } |
91 | + catch (Exception ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } | |
92 | + finally { le.Write(); } | |
93 | + } | |
94 | + | |
95 | + private class InterfaceErrorApplicationException : ApplicationException | |
96 | + { | |
97 | + public InterfaceErrorApplicationException(string typename, string methodname) : base($"Class '{typename}' does not implement 'public static void {methodname}()' action!") { } | |
98 | + public InterfaceErrorApplicationException(string typename) : base($"Class '{typename}' does not implement '{nameof(IWebServerHostedServiceStarter)}' interface!") { } | |
44 | 99 | } |
45 | 100 | /// <summary> |
46 | - /// A Hangfire rendszer elindítását, paraméterezését, konfigurálását és a külső iniciátorok meghívást végzi. | |
101 | + /// Egy hosted service elindítását, paraméterezését, konfigurálását és a külső iniciátor meghívást végzi. | |
47 | 102 | /// </summary> |
48 | - const string HANGFIRE = "HangfireBootstrapper:"; | |
49 | - const string HANGFIREDISABLEAUTOSTART = HANGFIRE + "disableautostart"; | |
50 | - const bool DISABLEAUTOSTARTDEFAULT = false; | |
51 | - const string HANGFIREDBCONNECTIONSTRING = HANGFIRE + "dbconnectionstring"; | |
52 | - const string HANGFIRESQLDBCONNECTIONSTRINGNAMEDEFAULT = "HANGFIRESQLDB"; | |
53 | - public static void Init(Action<object> externalinitializer=null) | |
103 | + /// <param name="externalinitializerstartmethod">az indító metódus</param> | |
104 | + /// <param name="externalinitializerstopmethod">a leállító metódus</param> | |
105 | + public static void Init(Action externalinitializerstartmethod, Action externalinitializerstopmethod) | |
54 | 106 | { |
55 | - var le = new DCLogEntry(LogLevel.Information, $"{typeof(HangfireBootstrapper).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); | |
107 | + var le = new DCLogEntry(LogLevel.Information, $"{typeof(WebServerHostedServiceStarter).FullName}.{nameof(Init)}"); | |
56 | 108 | try |
57 | 109 | { |
58 | - bool DisablAautoStart; | |
59 | - string disableautostartstring = ConfigurationManager.AppSettings[HANGFIREDISABLEAUTOSTART]; | |
60 | - if (string.IsNullOrWhiteSpace(disableautostartstring)) DisablAautoStart = DISABLEAUTOSTARTDEFAULT; | |
61 | - else if (disableautostartstring.ToLower() == bool.TrueString.ToLower()) DisablAautoStart = true; | |
62 | - else if (disableautostartstring.ToLower() != bool.FalseString.ToLower()) DisablAautoStart = false; | |
63 | - else DisablAautoStart = DISABLEAUTOSTARTDEFAULT; | |
110 | + _SetupAutoStart<WebServerHostedServiceStarter>(le: le); | |
111 | + IISHostedServiceStarterInstance._RegisterExternalInitializer(externalinitializerstartmethod, externalinitializerstopmethod, le); | |
112 | + IISHostedServiceStarterInstance._StartExternalInitializers(le); | |
113 | + } | |
114 | + catch (Exception ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } | |
115 | + finally { le.Write(); } | |
116 | + } | |
64 | 117 | |
65 | - le.AddDataField("DisablAautoStart", DisablAautoStart); | |
66 | - _InitConfig(externalinitializer, le); | |
67 | - HangfireBootstrapper.Instance._InstanceInitialize(DisablAautoStart,le); | |
68 | - ExecuteExternalInitializers(le); | |
118 | + /// <summary> | |
119 | + /// Több hosted service elindítását, paraméterezését, konfigurálását és a külső iniciátorok meghívást végzi. | |
120 | + /// </summary> | |
121 | + public static void Init(List<Tuple<Action, Action>> externalinitializerList) | |
122 | + { | |
123 | + var le = new DCLogEntry(LogLevel.Information, $"{typeof(WebServerHostedServiceStarter).FullName}.{nameof(Init)}"); | |
124 | + try | |
125 | + { | |
126 | + _SetupAutoStart<WebServerHostedServiceStarter>(le: le); | |
127 | + foreach (var ei in externalinitializerList) IISHostedServiceStarterInstance._RegisterExternalInitializer(ei.Item1, ei.Item2, le); | |
128 | + IISHostedServiceStarterInstance._StartExternalInitializers(le); | |
69 | 129 | } |
70 | 130 | catch (Exception ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } |
71 | 131 | finally { le.Write(); } |
72 | 132 | } |
73 | 133 | |
74 | 134 | /// <summary> |
75 | - /// A Hangfire rendszeer leállítását végzi; | |
135 | + /// A hosted serviceek leállítását végzi; | |
76 | 136 | /// Ezt a metódust meg kell hívni a IProcessHostPreloadClient működéséhez! |
77 | 137 | /// </summary> |
78 | 138 | public static void Stop() |
79 | 139 | { |
80 | - (new DCLogEntry(LogLevel.Information, $"{typeof(HangfireBootstrapper).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}")).Write(); | |
81 | - HangfireBootstrapper.Instance._Stop(); | |
140 | + var le = new DCLogEntry(LogLevel.Information, $"{typeof(WebServerHostedServiceStarter).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); | |
141 | + try { IISHostedServiceStarterInstance._StopExternalInitializers(le); } | |
142 | + catch (Exception ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } | |
143 | + finally { le.Write(); } | |
82 | 144 | } |
83 | 145 | |
84 | 146 | /// <summary> |
... | ... | @@ -87,11 +149,11 @@ namespace Vrh.Web.HangfireBootstrapperNS |
87 | 149 | /// <param name="parameters"></param> |
88 | 150 | public void Preload(string[] parameters) |
89 | 151 | { |
90 | - var le = new DCLogEntry(LogLevel.Information, $"{typeof(HangfireBootstrapper).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); | |
152 | + var le = new DCLogEntry(LogLevel.Information, $"{typeof(WebServerHostedServiceStarter).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); | |
91 | 153 | try |
92 | 154 | { |
93 | - _InstanceInitialize(le:le); | |
94 | - ExecuteExternalInitializers(le); | |
155 | + _SetupAutoStart<WebServerHostedServiceStarter>(disablemode: false, le: le); | |
156 | + _StartExternalInitializers(le); | |
95 | 157 | le.AddSuccessResult("SUCCESS"); |
96 | 158 | } |
97 | 159 | catch (Exception ex) { le.AddExceptionResult(ex);le.SetLogLevel(LogLevel.Error); } |
... | ... | @@ -101,77 +163,83 @@ namespace Vrh.Web.HangfireBootstrapperNS |
101 | 163 | /// <summary> |
102 | 164 | /// Kell legyen egy publikus paraméter nélküli konstruktor a webapp preload funkcióhoz!!! |
103 | 165 | /// </summary> |
104 | - public HangfireBootstrapper() { } | |
166 | + public WebServerHostedServiceStarter() { } | |
167 | + | |
105 | 168 | |
106 | 169 | #region private members |
107 | - private static void ExecuteExternalInitializers(DCLogEntry le) | |
170 | + void IRegisteredObject.Stop(bool immediate) { Stop(); } | |
171 | + private void _RegisterExternalInitializer(Action externalinitializerstartmethod, Action externalinitializerstopmethod, DCLogEntry le) | |
108 | 172 | { |
109 | - int numofall = externalinitializerList.Count(); | |
110 | - int counter = externalinitializerList.Count(); | |
111 | - if (numofall==0) | |
173 | + if (externalinitializerstartmethod != null) | |
112 | 174 | { |
113 | - le.AddDebugField("External initializer","Nothing to initialize!"); | |
175 | + externalinitializerList.Add(Tuple.Create(externalinitializerstartmethod, externalinitializerstopmethod)); | |
176 | + le?.AddDataField("ADD external initializer START", $"{externalinitializerstartmethod.Method.DeclaringType.FullName}.{externalinitializerstartmethod.Method.Name}()"); | |
177 | + le?.AddDataField("ADD external initializer STOP", $"{externalinitializerstopmethod.Method.DeclaringType.FullName}.{externalinitializerstopmethod.Method.Name}()"); | |
114 | 178 | } |
115 | - else | |
179 | + } | |
180 | + private void _StartExternalInitializers(DCLogEntry le) | |
181 | + { | |
182 | + lock (ExternalInitializerStarStopLocker) | |
116 | 183 | { |
184 | + int numofall = externalinitializerList.Count(); | |
185 | + int counter = externalinitializerList.Count(); | |
186 | + if (numofall == 0) { le.AddDebugField(nameof(_StartExternalInitializers), NOEXTERNALINITIALIZERSAREREGISTERED); return; } | |
187 | + | |
188 | + HostingEnvironment.RegisterObject(IISHostedServiceStarterInstance); | |
117 | 189 | foreach (var ei in externalinitializerList) |
118 | 190 | { |
119 | - var externalinitializername = $"External initializer: {ei.Method.DeclaringType.FullName}.{ei.Method.Name}()"; | |
120 | - try { ei.Invoke(HangfireBootstrapper.Instance._backgroundJobServer); le.AddDataField($"{externalinitializername} SUCCESS",$"{counter}of{numofall}"); } | |
121 | - catch (Exception ex) { le.AddDataField($"{externalinitializername} EXCEPTION", ex.Message); } | |
191 | + var externalinitializername = $"External initializer: {ei.Item1.Method.DeclaringType.FullName}.{ei.Item1.Method.Name}()"; | |
192 | + try { ei.Item1.Invoke(); le.AddDataField($"{externalinitializername} START SUCCESS", $"{counter}of{numofall}"); } | |
193 | + catch (Exception ex) { le.AddDataField($"{externalinitializername} START EXCEPTION", ex.Message); } | |
122 | 194 | counter++; |
123 | 195 | } |
124 | 196 | } |
125 | 197 | } |
126 | - | |
127 | - private void _InstanceInitialize(bool autostartsetupdisable =false,DCLogEntry le=null) | |
128 | - { | |
129 | - string HangfireSqlDBConnectionString = ConfigurationManager.AppSettings[HANGFIREDBCONNECTIONSTRING]; | |
130 | - if (string.IsNullOrWhiteSpace(HangfireSqlDBConnectionString)) HangfireSqlDBConnectionString = HANGFIRESQLDBCONNECTIONSTRINGNAMEDEFAULT; | |
131 | - le?.AddDataField("HangfireSqlDBConnectionString", HangfireSqlDBConnectionString); | |
132 | - SetupAutoStart(typeof(HangfireBootstrapper),disablemode:autostartsetupdisable,le:le); | |
133 | - HangfireBootstrapper.Instance.SqlDBconnectionstring = Vrh.XmlProcessing.ConnectionStringStore.GetSQL(HangfireSqlDBConnectionString); | |
134 | - HangfireBootstrapper.Instance._Start(); | |
135 | - } | |
136 | - | |
137 | - private static List<Action<object>> externalinitializerList = new List<Action<object>>(); | |
138 | - private static readonly HangfireBootstrapper Instance = new HangfireBootstrapper(); | |
139 | - private BackgroundJobServer _backgroundJobServer { get; set; } | |
140 | - private string SqlDBconnectionstring { get; set; } = null; | |
141 | - private readonly object _lockObject = new object(); | |
142 | - private bool _started; | |
143 | - | |
144 | - | |
145 | - private void _Start() | |
198 | + private void _StopExternalInitializers(DCLogEntry le) | |
146 | 199 | { |
147 | - lock (_lockObject) | |
200 | + lock (ExternalInitializerStarStopLocker) | |
148 | 201 | { |
149 | - if (_started) return; | |
150 | - _started = true; | |
202 | + int numofall = externalinitializerList.Count(); | |
203 | + int counter = externalinitializerList.Count(); | |
204 | + if (numofall == 0) { le.AddDebugField(nameof(_StopExternalInitializers), NOEXTERNALINITIALIZERSAREREGISTERED); return; } | |
151 | 205 | |
152 | - HostingEnvironment.RegisterObject(this); | |
153 | - GlobalConfiguration.Configuration | |
154 | - .UseSqlServerStorage(SqlDBconnectionstring) | |
155 | - // Specify other options here | |
156 | - ; | |
157 | - | |
158 | - _backgroundJobServer = new BackgroundJobServer(); | |
206 | + foreach (var ei in externalinitializerList) | |
207 | + { | |
208 | + var externalinitializername = $"External initializer: {ei.Item2.Method.DeclaringType.FullName}.{ei.Item2.Method.Name}()"; | |
209 | + try { ei.Item2.Invoke(); le.AddDataField($"{externalinitializername} STOP SUCCESS", $"{counter}of{numofall}"); } | |
210 | + catch (Exception ex) { le.AddDataField($"{externalinitializername} STOP EXCEPTION", ex.Message); } | |
211 | + counter++; | |
212 | + } | |
213 | + HostingEnvironment.UnregisterObject(IISHostedServiceStarterInstance); | |
159 | 214 | } |
160 | 215 | } |
161 | 216 | |
162 | - private void _Stop() | |
217 | + private object ExternalInitializerStarStopLocker = new object(); | |
218 | + private static readonly WebServerHostedServiceStarter IISHostedServiceStarterInstance = new WebServerHostedServiceStarter(); | |
219 | + private static List<Tuple<Action, Action>> externalinitializerList = new List<Tuple<Action, Action>>(); | |
220 | + private static bool Config_DisablAutoStart | |
163 | 221 | { |
164 | - lock (_lockObject) | |
222 | + get | |
165 | 223 | { |
166 | - if (_backgroundJobServer != null) { _backgroundJobServer.Dispose(); } | |
167 | - HostingEnvironment.UnregisterObject(this); | |
224 | + if (!config_disablautostart.HasValue) | |
225 | + { | |
226 | + string disableautostartstring = ConfigurationManager.AppSettings[DISABLEAUTOSTART]; | |
227 | + if (string.IsNullOrWhiteSpace(disableautostartstring)) config_disablautostart = DISABLEAUTOSTARTDEFAULT; | |
228 | + else if (disableautostartstring.ToLower() == bool.TrueString.ToLower()) config_disablautostart = true; | |
229 | + else if (disableautostartstring.ToLower() != bool.FalseString.ToLower()) config_disablautostart = false; | |
230 | + else config_disablautostart = DISABLEAUTOSTARTDEFAULT; | |
231 | + } | |
232 | + return config_disablautostart.Value; | |
168 | 233 | } |
169 | 234 | } |
170 | - | |
171 | - void IRegisteredObject.Stop(bool immediate) { _Stop(); } | |
235 | + private static bool? config_disablautostart = null; | |
236 | + private const string IISHOSTEDSERVICESTARTER = "IISHostedServiceStarter:"; | |
237 | + private const string DISABLEAUTOSTART = IISHOSTEDSERVICESTARTER + "disableautostart"; | |
238 | + private const bool DISABLEAUTOSTARTDEFAULT = false; | |
239 | + private const string NOEXTERNALINITIALIZERSAREREGISTERED = "No external initializers are registered!"; | |
172 | 240 | #endregion private members |
173 | 241 | |
174 | - #region private method - SetupAutoStart | |
242 | + #region private method - _SetupAutoStart | |
175 | 243 | /// <summary> |
176 | 244 | /// Beállítja az autostart és alwaysrunning és a preload paramétereket a megadott websitra, |
177 | 245 | /// web alkalmazásra és application pool-ra vonatkozóan. |
... | ... | @@ -204,14 +272,16 @@ namespace Vrh.Web.HangfireBootstrapperNS |
204 | 272 | /// <param name="webapplicationname">a web app neve; alapértelmezés:a tartalmazó web app</param> |
205 | 273 | /// <param name="applicationpoolname">az app pool neve; alapértelmezés:a tartalmazó pool</param> |
206 | 274 | /// <returns></returns> |
207 | - private static void SetupAutoStart(Type serviceAutoStartProviderType, string websitename = null, string webapplicationname = null, string applicationpoolname = null, bool disablemode = false, DCLogEntry le = null) | |
275 | + private static void _SetupAutoStart<T>(string websitename = null, string webapplicationname = null, string applicationpoolname = null, bool? disablemode = null, DCLogEntry le = null) | |
276 | + where T: IProcessHostPreloadClient | |
208 | 277 | { |
278 | + Type serviceAutoStartProviderType = typeof(T); | |
209 | 279 | const string CONFIGFILEDIRECTORY = @"inetsrv\config"; |
210 | 280 | const string CONFIGFILENAME = @"applicationHost.config"; |
211 | 281 | //const string FILEPATH = @"C:\temp\applicationHost.config"; |
212 | - | |
282 | + Thread.Sleep(20000); | |
213 | 283 | bool writele = le == null; |
214 | - if (le == null) { le = new DCLogEntry(LogLevel.Information, $"{typeof(HangfireBootstrapper).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); }; | |
284 | + if (le == null) { le = new DCLogEntry(LogLevel.Information, $"{typeof(WebServerHostedServiceStarter).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); }; | |
215 | 285 | try |
216 | 286 | { |
217 | 287 | websitename = websitename ?? HostingEnvironment.SiteName; //websitename = System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName(); |
... | ... | @@ -231,6 +301,9 @@ namespace Vrh.Web.HangfireBootstrapperNS |
231 | 301 | le.AddDataField("SetupAutoStart serviceAutoStartProviderTypeFullName", serviceAutoStartProviderTypeFullName); |
232 | 302 | le.AddDataField("SetupAutoStart serviceAutoStartProviderAssassemblyName", serviceAutoStartProviderAssassemblyName); |
233 | 303 | |
304 | + if (!disablemode.HasValue) disablemode = Config_DisablAutoStart; | |
305 | + le.AddDataField("DisablAautoStart", disablemode.Value); | |
306 | + | |
234 | 307 | string filecontent; |
235 | 308 | bool configchanged; |
236 | 309 | lock (lockerFile) |
... | ... | @@ -253,7 +326,7 @@ namespace Vrh.Web.HangfireBootstrapperNS |
253 | 326 | } |
254 | 327 | |
255 | 328 | reader = new StreamReader(file, Encoding.ASCII); |
256 | - filecontent = ProcessFileContent(le, reader.ReadToEnd(), applicationpoolname, websitename, webapplicationname, autostartprovidername, serviceAutoStartProviderAssassemblyName, serviceAutoStartProviderTypeFullName, disablemode); | |
329 | + filecontent = ProcessFileContent(le, reader.ReadToEnd(), applicationpoolname, websitename, webapplicationname, autostartprovidername, serviceAutoStartProviderAssassemblyName, serviceAutoStartProviderTypeFullName, disablemode.Value); | |
257 | 330 | configchanged = filecontent != null; |
258 | 331 | if (configchanged) |
259 | 332 | { |
... | ... | @@ -265,12 +338,12 @@ namespace Vrh.Web.HangfireBootstrapperNS |
265 | 338 | } |
266 | 339 | else |
267 | 340 | { |
268 | - filecontent = ProcessFileContent(le, System.IO.File.ReadAllText(configfilepath), applicationpoolname, websitename, webapplicationname, autostartprovidername, serviceAutoStartProviderAssassemblyName, serviceAutoStartProviderTypeFullName, disablemode); | |
341 | + filecontent = ProcessFileContent(le, System.IO.File.ReadAllText(configfilepath), applicationpoolname, websitename, webapplicationname, autostartprovidername, serviceAutoStartProviderAssassemblyName, serviceAutoStartProviderTypeFullName, disablemode.Value); | |
269 | 342 | configchanged = filecontent != null; |
270 | 343 | if (configchanged) System.IO.File.WriteAllText(configfilepath, filecontent); |
271 | 344 | } |
272 | 345 | } |
273 | - string modetxt = disablemode ? "DISABLED" : "ENABLED"; | |
346 | + string modetxt = disablemode.Value ? "DISABLED" : "ENABLED"; | |
274 | 347 | le.AddDataField("SetupAutoStart SUCCESS RESULT",configchanged ? modetxt : $"NO CHANGE, ALREADY {modetxt}"); |
275 | 348 | } |
276 | 349 | catch (Exception ex) { le.AddDataField("SetupAutoStart EXCEPTION",ex.Message); le.SetLogLevel(LogLevel.Error); return; } |
... | ... | @@ -405,6 +478,6 @@ namespace Vrh.Web.HangfireBootstrapperNS |
405 | 478 | .FirstOrDefault(app => app.Path == HttpRuntime.AppDomainAppVirtualPath)? |
406 | 479 | .ApplicationPoolName; |
407 | 480 | } |
408 | - #endregion private method - SetupAutoStart | |
481 | + #endregion private method - _SetupAutoStart | |
409 | 482 | } |
410 | 483 | } | ... | ... |
Vrh.iScheduler/Monitor .cs
... | ... | @@ -16,107 +16,237 @@ using System.Data.SqlClient; |
16 | 16 | using System.Xml.Linq; |
17 | 17 | using Hangfire; |
18 | 18 | using Hangfire.Storage; |
19 | +using System.Web.Hosting; | |
20 | +using System.Configuration; | |
21 | + | |
19 | 22 | namespace Vrh.iScheduler |
20 | 23 | { |
21 | - | |
22 | - public class Monitor : IDisposable | |
24 | + public class WAHostedMonitorHangfire | |
23 | 25 | { |
24 | - public static void InitHangfire(object parameters) | |
26 | + /// <summary> | |
27 | + /// A Hangfire alrendszer inicializálását+indítását, vagy a leállítását végzi | |
28 | + /// </summary> | |
29 | + /// <param name="start">true:inicalizálás/indítás; false:leállítás</param> | |
30 | + public static void Start() | |
25 | 31 | { |
26 | - string ischedulerMonitorXml = "config=ALMiSchedulerMonitor";//TODO:hogy lehet ezt paraméterben átadni?????? | |
27 | - string ischedulerXml = ""; // vagy "config=ALMiScheduler;"; | |
28 | - var m_xmlp = new iSchedulerXMLProcessor(ischedulerMonitorXml, ischedulerXml); | |
29 | - Monitor.SetiSchedulerCommonXMLProcessor(m_xmlp); | |
30 | - if (m_xmlp.EnableWebAppExecution && m_xmlp.CheckInterval > 0) | |
32 | + var le = new DCLogEntry(LogLevel.Information, $"{typeof(WAHostedMonitorHangfire).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); | |
33 | + try | |
31 | 34 | { |
35 | + _MonitorHangfireInstance._StartHangfire(le); | |
36 | + string ischedulerMonitorXml = "config=ALMiSchedulerMonitor";//TODO:hogy lehet ezt paraméterben átadni?????? | |
37 | + string ischedulerXml = ""; // vagy "config=ALMiScheduler;"; | |
38 | + var m_xmlp = new iSchedulerXMLProcessor(ischedulerMonitorXml, ischedulerXml); | |
39 | + Monitor.SetiSchedulerCommonXMLProcessor(m_xmlp); | |
40 | + if (m_xmlp.EnableWebAppExecution && m_xmlp.CheckInterval > 0) | |
41 | + { | |
42 | + IntervalCronExpression = Cron.MinuteInterval((int)(m_xmlp.CheckInterval / 60));//"*/1 * * * *" | |
43 | + //RecurringJob.RemoveIfExists("ischedulermonitorcycle"); | |
44 | + RecurringJob.AddOrUpdate("ischedulermonitorcycle", () => new Monitor().Examination(null), IntervalCronExpression); | |
45 | + //var HanfireJobId = BackgroundJob.Enqueue(() => new Monitor().Examination(null)); | |
46 | + //RecurringJob.AddOrUpdate("ischedulermonitorcycle", () => new Monitor(m_xmlp).Examination(null), intervalcron); //minutes interval | |
47 | + //RecurringJob.AddOrUpdate("ischedulermonitorcycle", () => new Monitor(m_xmlp).Examination(null), $"{(int)(m_xmlp.CheckInterval / 60)} * * * *"); // cron expression | |
48 | + } | |
49 | + } | |
50 | + catch (Exception ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } | |
51 | + finally { le.Write(); } | |
52 | + } | |
32 | 53 | |
33 | - //Cron Expression | |
34 | - // <minute> <hour> <day-of-month> <month> <day-of-week> | |
35 | - // <minute>:0-59 | |
36 | - // <hour>:0-23 | |
37 | - // <day-of-month>:1-31 | |
38 | - // <month>:1-12 | |
39 | - // <day-of-week>:0-6 (Sunday to Saturday; 7 is Sunday on some systems) | |
40 | - //Special Characters in Cron Expression | |
41 | - // * (all) all values. event should happen for every time unit. For example, “*” in the<minute> field means “for every minute.” | |
42 | - // ? (any) any value. used for the <day-of-month> and <day-of-week> fields. For example “?” in the<day-of-week> field and 5 in the <day-of-month> | |
43 | - // field means “5th of every month” irrespective of what day is this of the week. | |
44 | - // – (range) value range. For example, “10-11” in the<hour> field means “10th and 11th hours.” | |
45 | - // , (values) multiple values. For example, “MON, WED, FRI“ in <day-of-week> field means on the days “Monday, Wednesday and Friday.” | |
46 | - // / (increments) specifies the incremental values.For example, a “5/15” in the<minute> field means at “5, 20, 35 and 50 minutes of an hour.” | |
47 | - // L (last) has different meanings when used in various fields. For example, if it's applied in the <day-of-month> field, it means last day of the month, | |
48 | - // i.e. “31st of January” and so on as per the calendar month. It can be used with an offset value, like “L-3”, | |
49 | - // which denotes the “third to last day of the calendar month.” In <day-of-week>, it specifies the “last day of a week.” It can also be used with | |
50 | - // another value in <day-of-week>, like “6L”, which denotes the “last Friday.” | |
51 | - // W (weekday) determines the weekday (Monday to Friday) nearest to a given day of the month.For example, if we specify “10W” in the<day-of-month> field, | |
52 | - // it means the “weekday near to 10th of that month.” So if “10th” is a Saturday, the job will be triggered on “9th,” and if “10th” is a Sunday, | |
53 | - // it will trigger on “11th.” If we specify “1W” in <day-of-month> and if “1st” is Saturday, the job will be triggered on “3rd,” which is Monday, | |
54 | - // and it will not jump back to the previous month. | |
55 | - // # specifies the “N-th” occurrence of a weekday of the month, for example, “third Friday of the month” can be indicated as “6#3”. | |
56 | - //Cron Special Strings | |
57 | - // run once at the startup: "@reboot" | |
58 | - // run once a year: "@yearly" or "@annualy" (="0 0 1 1 *") | |
59 | - // run once a month: "@monthly" (="0 0 1 * *") | |
60 | - // run once a week: "@weekly" (="0 0 * * 0") | |
61 | - // run once a day: "@daily" or "@midnight" (="0 0 * * *") | |
62 | - // run hourly: "@hourly" (="0 * * * *") | |
54 | + public static void Stop() | |
55 | + { | |
56 | + var le = new DCLogEntry(LogLevel.Information, $"{typeof(WAHostedMonitorHangfire).FullName}.{System.Reflection.MethodBase.GetCurrentMethod().Name}"); | |
57 | + try { _MonitorHangfireInstance._StopHangfire(le); } | |
58 | + catch (Exception ex) { le.AddExceptionResult(ex); le.SetLogLevel(LogLevel.Error); } | |
59 | + finally { le.Write(); } | |
60 | + } | |
63 | 61 | |
64 | - //At 12:00pm (noon) every day: "0 12 * * ?" | |
65 | - //At Every five minutes starting at 1pm and ending at 1:55pm and then starting at 6pm and ending at 6:55pm, every day: "0/5 13,18 * * ?" | |
66 | - //At Every minute starting at 1pm and ending at 1:05pm, every day: "0-5 13 * * ?" | |
67 | - //At 1:15pm and 1:45pm every Tuesday in the month of June: "15,45 13 ? 6 Tue" | |
68 | - //At 9:30am every Monday, Tuesday, Wednesday, Thursday and Friday: "30 9 ? *MON - FRI" | |
69 | - //At 9:30am on the 15th day of every month: "30 9 15 * ?" | |
70 | - //At 6pm on the last day of every month: "0 18 L * ?" | |
71 | - //At 6pm on the third to last day of every month: "0 18 L - 3 * ?" | |
72 | - //At 10:30am on the last Thursday of every month: "30 10 ? *5L" | |
73 | - //At 10am on the third Monday of every month: "0 10 ? *2#3" | |
74 | - //At 12 midnight on every 5th day, starting from the 10th until the end of the month: "0 0 10 / 5 * ?" | |
75 | 62 | |
76 | - //At every hour: "0 * * * *" | |
77 | - //At every hour: "@hourly" | |
78 | - //At once a day at midnight: "0 0 * * *" | |
79 | - //At every Sunday at midnight: "0 0 * * 0" | |
80 | - //At every hour on Mondays: "0 * * *1" | |
81 | - //At twice a day at 6am and 6pm: "0 6,18 * * *" | |
82 | - //At every 10 minutes: "*/10 * * * *" | |
83 | - //At every minute on July 20: "* * 20 7 *" | |
84 | - //At every weekday(Monday to Friday) at 10pm: "0 22 * * 1-5" | |
85 | - //At at midnight every Tuesday: "0 0 * * 2 *" | |
86 | - //At every minute during January, February, and May "* * * 1,2,5 *" | |
87 | - //At every 10 minutes at 5am, starting from 5:10am: "10-59/10 5 * * *" | |
88 | - //At quarterly on the first day of the month at 8am "0 8 1 */3 *" | |
89 | - //At every time you turn on the system: "@reboot" | |
90 | - //At the first Monday of each month, at 8am: "0 8 1-7 * 1" | |
91 | - //At every Sunday at 4:05 am: "5 4 * * 0" | |
92 | - //At at 9:15 pm on the 1st and 20th of every month: "15 9 1,20 * *" | |
93 | - //At at midnight every Wednesday between the 1st and 15th of every month: "0 0 1,15 * 3" | |
94 | - //At the first day of every month at 2:15pm: "15 14 1 * *" | |
95 | - //At every day from Monday to Friday every hour from 8 to 5pm: "00 08-17 * * 1-5" | |
96 | - //At every January 1st at 6:15am: "15 6 1 1 *" | |
97 | - //At at midnight on the 15th of every month: "0 0 15 * *" | |
98 | - //At every Monday and Friday: "* * * * 1,5" | |
63 | + /// <summary> | |
64 | + /// Cron Expression | |
65 | + /// <minute> <hour> <day-of-month> <month> <day-of-week> | |
66 | + /// <minute>:0-59 | |
67 | + /// <hour>:0-23 | |
68 | + /// <day-of-month>:1-31 | |
69 | + /// <month>:1-12 | |
70 | + /// <day-of-week>:0-6 (Sunday to Saturday; 7 is Sunday on some systems) | |
71 | + /// Special Characters in Cron Expression | |
72 | + /// * (all) all values. event should happen for every time unit.For example, “*” in the<minute> field means “for every minute.” | |
73 | + /// ? (any) any value.used for the<day-of-month> and <day-of-week> fields.For example “?” in the<day-of-week> field and 5 in the<day-of-month> | |
74 | + /// field means “5th of every month” irrespective of what day is this of the week. | |
75 | + /// – (range) value range.For example, “10-11” in the<hour> field means “10th and 11th hours.” | |
76 | + /// , (values) multiple values.For example, “MON, WED, FRI“ in <day-of-week> field means on the days “Monday, Wednesday and Friday.” | |
77 | + /// / (increments) specifies the incremental values.For example, a “5/15” in the<minute> field means at “5, 20, 35 and 50 minutes of an hour.” | |
78 | + /// | |
79 | + /// L (last) has different meanings when used in various fields. For example, if it's applied in the <day-of-month> field, it means last day of the month, | |
80 | + /// i.e. “31st of January” and so on as per the calendar month. It can be used with an offset value, like “L-3”, | |
81 | + /// which denotes the “third to last day of the calendar month.” In<day-of-week>, it specifies the “last day of a week.” It can also be used with | |
82 | + /// another value in <day-of-week>, like “6L”, which denotes the “last Friday.” | |
83 | + /// | |
84 | + /// W (weekday) determines the weekday (Monday to Friday) nearest to a given day of the month.For example, if we specify “10W” in the<day-of-month> field, | |
85 | + /// it means the “weekday near to 10th of that month.” So if “10th” is a Saturday, the job will be triggered on “9th,” and if “10th” is a Sunday, | |
86 | + /// it will trigger on “11th.” If we specify “1W” in <day-of-month> and if “1st” is Saturday, the job will be triggered on “3rd,” which is Monday, | |
87 | + /// and it will not jump back to the previous month. | |
88 | + /// # specifies the “N-th” occurrence of a weekday of the month, for example, “third Friday of the month” can be indicated as “6#3”. | |
89 | + /// Cron Special Strings | |
90 | + /// run once at the startup: "@reboot" | |
91 | + /// run once a year: "@yearly" or "@annualy" (= "0 0 1 1 *") | |
92 | + /// run once a month: "@monthly" (="0 0 1 * *") | |
93 | + /// run once a week: "@weekly" (="0 0 * * 0") | |
94 | + /// run once a day: "@daily" or "@midnight" (="0 0 * * *") | |
95 | + /// run hourly: "@hourly" (="0 * * * *") | |
96 | + /// | |
97 | + /// Cron samples | |
98 | + /// At 12:00pm(noon) every day: "0 12 * * ?" | |
99 | + /// At Every five minutes starting at 1pm and ending at 1:55pm and then starting at 6pm and ending at 6:55pm, every day: "0/5 13,18 * * ?" | |
100 | + /// At Every minute starting at 1pm and ending at 1:05pm, every day: "0-5 13 * * ?" | |
101 | + /// At 1:15pm and 1:45pm every Tuesday in the month of June: "15,45 13 ? 6 Tue" | |
102 | + /// At 9:30am every Monday, Tuesday, Wednesday, Thursday and Friday: "30 9 ? *MON - FRI" | |
103 | + /// At 9:30am on the 15th day of every month: "30 9 15 * ?" | |
104 | + /// At 6pm on the last day of every month: "0 18 L * ?" | |
105 | + /// At 6pm on the third to last day of every month: "0 18 L - 3 * ?" | |
106 | + /// At 10:30am on the last Thursday of every month: "30 10 ? *5L" | |
107 | + /// At 10am on the third Monday of every month: "0 10 ? *2#3" | |
108 | + /// At 12 midnight on every 5th day, starting from the 10th until the end of the month: "0 0 10 / 5 * ?" | |
109 | + /// | |
110 | + /// At every hour: "0 * * * *" | |
111 | + /// At every hour: "@hourly" | |
112 | + /// At once a day at midnight: "0 0 * * *" | |
113 | + /// At every Sunday at midnight: "0 0 * * 0" | |
114 | + /// At every hour on Mondays: "0 * * *1" | |
115 | + /// At twice a day at 6am and 6pm: "0 6,18 * * *" | |
116 | + /// At every 10 minutes: "*/10 * * * *" | |
117 | + /// At every minute on July 20: "* * 20 7 *" | |
118 | + /// At every weekday(Monday to Friday) at 10pm: "0 22 * * 1-5" | |
119 | + /// At at midnight every Tuesday: "0 0 * * 2 *" | |
120 | + /// At every minute during January, February, and May "* * * 1,2,5 *" | |
121 | + /// At every 10 minutes at 5am, starting from 5:10am: "10-59/10 5 * * *" | |
122 | + /// At quarterly on the first day of the month at 8am "0 8 1 */3 *" | |
123 | + /// At every time you turn on the system: "@reboot" | |
124 | + /// At the first Monday of each month, at 8am: "0 8 1-7 * 1" | |
125 | + /// At every Sunday at 4:05 am: "5 4 * * 0" | |
126 | + /// At at 9:15 pm on the 1st and 20th of every month: "15 9 1,20 * *" | |
127 | + /// At at midnight every Wednesday between the 1st and 15th of every month: "0 0 1,15 * 3" | |
128 | + /// At the first day of every month at 2:15pm: "15 14 1 * *" | |
129 | + /// At every day from Monday to Friday every hour from 8 to 5pm: "00 08-17 * * 1-5" | |
130 | + /// At every January 1st at 6:15am: "15 6 1 1 *" | |
131 | + /// At at midnight on the 15th of every month: "0 0 15 * *" | |
132 | + /// At every Monday and Friday: "* * * * 1,5" | |
133 | + /// | |
134 | + /// At Every Minute of Every Day: "* * * * *" or "0-59 0-23 0-31 0-12 0-7" | |
135 | + /// At Every 10 Minutes of Every Day: "*/10 * * * *" or "0-59/10 * * * *" or "0,10,20,30,40,50 * * * *" | |
136 | + /// At Every 5 Minutes of the 6am hour starting at 6:07 (tu run at 6:07, 6:012, 6:17, 6:22, 6:27, and so on until 6:57):"07-59/5 06 * * *" | |
137 | + /// At Every day at midnight: "0 0 * * *" or "0 0 * * 0-7" | |
138 | + /// At Thrice Daily: "0 */8 * * *" or "0 0-23/8 * * *" or "0 0,8,16 * * *" | |
139 | + /// At Every weekday at 6am: "0 06 * * 1-5" | |
140 | + /// At Weekends at 6am: "0 06 * * 6,7" or "0 06 * * 6-7" | |
141 | + /// At Once a month on the 20th at 6am: "0 06 20 * *" | |
142 | + /// At Every 4 days at 6am: "0 06 */4 * *" | |
143 | + /// At Every 4 Months at 6am on the 10th: "0 06 10 */4 *" | |
144 | + /// </summary> | |
145 | + private static string IntervalCronExpression = null; | |
146 | + private static WAHostedMonitorHangfire _MonitorHangfireInstance = new WAHostedMonitorHangfire(); | |
99 | 147 | |
100 | - //At Every Minute of Every Day: "* * * * *" or "0-59 0-23 0-31 0-12 0-7" | |
101 | - //At Every 10 Minutes of Every Day: "*/10 * * * *" or "0-59/10 * * * *" or "0,10,20,30,40,50 * * * *" | |
102 | - //At Every 5 Minutes of the 6am hour starting at 6:07 (tu run at 6:07, 6:012, 6:17, 6:22, 6:27, and so on until 6:57):"07-59/5 06 * * *" | |
103 | - //At Every day at midnight: "0 0 * * *" or "0 0 * * 0-7" | |
104 | - //At Thrice Daily: "0 */8 * * *" or "0 0-23/8 * * *" or "0 0,8,16 * * *" | |
105 | - //At Every weekday at 6am: "0 06 * * 1-5" | |
106 | - //At Weekends at 6am: "0 06 * * 6,7" or "0 06 * * 6-7" | |
107 | - //At Once a month on the 20th at 6am: "0 06 20 * *" | |
108 | - //At Every 4 days at 6am: "0 06 */4 * *" | |
109 | - //At Every 4 Months at 6am on the 10th: "0 06 10 */4 *" | |
148 | + private BackgroundJobServer _HangfireBackgroundJobServer { get; set; } | |
149 | + private static readonly object _HangfireStarterLocker = new object(); | |
150 | + private static bool _HangFireRunning = false; | |
151 | + const string HANGFIRE = "HangfireBootstrapper:"; | |
152 | + const string HANGFIREDBCONNECTIONSTRING = HANGFIRE + "dbconnectionstring"; | |
153 | + const string HANGFIRESQLDBCONNECTIONSTRINGNAMEDEFAULT = "HANGFIRESQLDB"; | |
154 | + private void _StartHangfire(DCLogEntry le) | |
155 | + { | |
156 | + lock (_HangfireStarterLocker) | |
157 | + { | |
158 | + le?.AddDataField("HangfireSqlDBConnectionString", Config_HangFireConnectionString); | |
110 | 159 | |
160 | + GlobalConfiguration.Configuration | |
161 | + .UseSqlServerStorage(Config_HangFireConnectionString) | |
162 | + // Specify other options here | |
163 | + ; | |
164 | + _HangfireBackgroundJobServer = new BackgroundJobServer(); | |
165 | + _HangFireRunning = true; | |
166 | + } | |
167 | + } | |
168 | + private void _StopHangfire(DCLogEntry le) | |
169 | + { | |
170 | + lock (_HangfireStarterLocker) | |
171 | + { | |
172 | + if (!_HangFireRunning) return; | |
173 | + le?.AddDataField("Function", nameof(_StopHangfire)); | |
174 | + if (_HangfireBackgroundJobServer != null) { _HangfireBackgroundJobServer.Dispose(); } | |
175 | + _HangFireRunning = false; | |
176 | + } | |
177 | + } | |
178 | + private string Config_HangFireConnectionString | |
179 | + { | |
180 | + get | |
181 | + { | |
182 | + if (config_hangfireconnectionstring == null) | |
183 | + { | |
184 | + string HangfireSqlDBConnectionString = ConfigurationManager.AppSettings[HANGFIREDBCONNECTIONSTRING]; | |
185 | + if (string.IsNullOrWhiteSpace(HangfireSqlDBConnectionString)) HangfireSqlDBConnectionString = HANGFIRESQLDBCONNECTIONSTRINGNAMEDEFAULT; | |
186 | + config_hangfireconnectionstring = ConnectionStringStore.GetSQL(HangfireSqlDBConnectionString); | |
187 | + } | |
188 | + return config_hangfireconnectionstring; | |
189 | + } | |
190 | + } | |
191 | + private string config_hangfireconnectionstring = null; | |
192 | + } | |
193 | +} | |
194 | +namespace Vrh.iScheduler | |
195 | +{ | |
196 | + public class WAHostedMonitor : Monitor | |
197 | + { | |
198 | + public static void Start() | |
199 | + { | |
200 | + MonitorInstance = new Monitor(Config_scheduleMonitorXmlPath, Config_scheduleXmlPath); | |
201 | + MonitorInstance.Start(); | |
202 | + new DCLogEntry(LogLevel.Information, "iSchedulerMonitor started.").Write(); | |
203 | + } | |
204 | + public static void Stop() | |
205 | + { | |
206 | + MonitorInstance.Stop(); | |
207 | + MonitorInstance.Dispose(); | |
208 | + new DCLogEntry(LogLevel.Information, "iSchedulerMonitor stopped.").Write(); | |
209 | + } | |
111 | 210 | |
112 | - string intervalcron = Cron.MinuteInterval((int)(m_xmlp.CheckInterval / 60));//"*/1 * * * *" | |
113 | - //RecurringJob.RemoveIfExists("ischedulermonitorcycle"); | |
114 | - RecurringJob.AddOrUpdate("ischedulermonitorcycle", () => new Monitor().Examination(null), intervalcron); | |
115 | - //var HanfireJobId = BackgroundJob.Enqueue(() => new Monitor().Examination(null)); | |
116 | - //RecurringJob.AddOrUpdate("ischedulermonitorcycle", () => new Monitor(m_xmlp).Examination(null), intervalcron); //minutes interval | |
117 | - //RecurringJob.AddOrUpdate("ischedulermonitorcycle", () => new Monitor(m_xmlp).Examination(null), $"{(int)(m_xmlp.CheckInterval / 60)} * * * *"); // cron expression | |
211 | + #region private members | |
212 | + private static string Config_scheduleMonitorXmlPath | |
213 | + { | |
214 | + get | |
215 | + { | |
216 | + if (config_schedulemonitorxmlpath == null) | |
217 | + { | |
218 | + string schedulemonitorxmlpath = ConfigurationManager.AppSettings[ISCHEDULERMONITORXMLPATH]; | |
219 | + config_schedulemonitorxmlpath = ConnectionStringStore.GetSQL(schedulemonitorxmlpath); | |
220 | + } | |
221 | + return config_schedulemonitorxmlpath; | |
222 | + } | |
223 | + } | |
224 | + private static string config_schedulemonitorxmlpath = null; | |
225 | + private static string Config_scheduleXmlPath | |
226 | + { | |
227 | + get | |
228 | + { | |
229 | + if (config_schedulexmlpath == null) | |
230 | + { | |
231 | + string schedulexmlpath = ConfigurationManager.AppSettings[ISCHEDULERXMLPATH]; | |
232 | + config_schedulexmlpath = ConnectionStringStore.GetSQL(schedulexmlpath); | |
233 | + } | |
234 | + return config_schedulexmlpath; | |
118 | 235 | } |
119 | 236 | } |
237 | + private static string config_schedulexmlpath = null; | |
238 | + const string ISCHEDULER = "iScheduler:"; | |
239 | + const string ISCHEDULERMONITORXMLPATH = ISCHEDULER + "monitorxmlpath"; | |
240 | + const string ISCHEDULERXMLPATH = ISCHEDULER + "xmlpath"; | |
241 | + private static Monitor MonitorInstance; | |
242 | + #endregion private members | |
243 | + } | |
244 | +} | |
245 | + | |
246 | +namespace Vrh.iScheduler | |
247 | +{ | |
248 | + public class Monitor : IDisposable | |
249 | + { | |
120 | 250 | #region Enums |
121 | 251 | /// <summary> |
122 | 252 | /// Ütemezések lehetséges állapotai. |
... | ... | @@ -140,7 +270,7 @@ namespace Vrh.iScheduler |
140 | 270 | } |
141 | 271 | #endregion Enums |
142 | 272 | |
143 | - #region Privates | |
273 | + #region Private members | |
144 | 274 | |
145 | 275 | private Timer m_timer; |
146 | 276 | private iSchedulerXMLProcessor m_xmlp; |
... | ... | @@ -149,7 +279,7 @@ namespace Vrh.iScheduler |
149 | 279 | { |
150 | 280 | CommonM_xmlp = m_xmlp; |
151 | 281 | } |
152 | - #endregion Privates | |
282 | + #endregion Private members | |
153 | 283 | |
154 | 284 | #region Constructor |
155 | 285 | |
... | ... | @@ -198,6 +328,7 @@ namespace Vrh.iScheduler |
198 | 328 | } |
199 | 329 | #endregion Constructor |
200 | 330 | |
331 | + #region public methods - Start,Stop | |
201 | 332 | public void Start() |
202 | 333 | { |
203 | 334 | new DCLogEntry(LogLevel.Information, "iSchedulerMonitor started.").Write(); |
... | ... | @@ -208,6 +339,7 @@ namespace Vrh.iScheduler |
208 | 339 | m_timer.Stop(); |
209 | 340 | new DCLogEntry(LogLevel.Information, "iSchedulerMonitor stopped.").Write(); |
210 | 341 | } |
342 | + #endregion public methods - Start,Stop | |
211 | 343 | |
212 | 344 | #region Private methods |
213 | 345 | ... | ... |
Vrh.iScheduler/Properties/AssemblyInfo.cs
... | ... | @@ -32,7 +32,7 @@ using System.Runtime.InteropServices; |
32 | 32 | // You can specify all the values or you can default the Build and Revision Numbers |
33 | 33 | // by using the '*' as shown below: |
34 | 34 | // [assembly: AssemblyVersion("1.0.*")] |
35 | -[assembly: AssemblyVersion("3.2.1.0")] | |
36 | -[assembly: AssemblyFileVersion("3.2.1.0")] | |
37 | -[assembly: AssemblyInformationalVersion("3.2.1")] | |
35 | +[assembly: AssemblyVersion("3.3.0.0")] | |
36 | +[assembly: AssemblyFileVersion("3.3.0.0")] | |
37 | +[assembly: AssemblyInformationalVersion("3.3.0")] | |
38 | 38 | ... | ... |