2020namespace FacturaScripts \Core \Model ;
2121
2222use Closure ;
23- use Exception ;
23+ use Error ;
2424use FacturaScripts \Core \Template \ModelClass ;
2525use FacturaScripts \Core \Template \ModelTrait ;
2626use FacturaScripts \Core \Tools ;
2727use FacturaScripts \Core \Where ;
28+ use Throwable ;
2829
2930/**
3031 * Class to store log information when a plugin is executed from cron.
@@ -51,12 +52,18 @@ class CronJob extends ModelClass
5152 /** @var bool */
5253 public $ failed ;
5354
55+ /** @var int */
56+ public $ fails ;
57+
5458 /** @var int */
5559 public $ id ;
5660
5761 /** @var string */
5862 public $ jobname ;
5963
64+ /** @var float */
65+ public $ last_duration ;
66+
6067 /** @var bool */
6168 private $ overlapping = false ;
6269
@@ -66,6 +73,9 @@ class CronJob extends ModelClass
6673 /** @var bool */
6774 private $ ready = false ;
6875
76+ /** @var int */
77+ public $ running ;
78+
6979 /** @var float */
7080 private $ start ;
7181
@@ -77,6 +87,9 @@ public function clear(): void
7787 $ this ->duration = 0.0 ;
7888 $ this ->enabled = true ;
7989 $ this ->failed = false ;
90+ $ this ->fails = 0 ;
91+ $ this ->last_duration = 0.0 ;
92+ $ this ->running = 0 ;
8093 }
8194
8295 public function every (string $ period ): self
@@ -166,6 +179,8 @@ public function run(Closure $function): bool
166179 $ this ->start = microtime (true );
167180 $ this ->done = false ;
168181 $ this ->failed = false ;
182+ $ this ->running ++;
183+ $ this ->last_duration = $ this ->duration ;
169184 $ this ->duration = 0.0 ;
170185 $ this ->date = Tools::dateTime ();
171186 if (false === $ this ->save ()) {
@@ -178,22 +193,42 @@ public function run(Closure $function): bool
178193
179194 try {
180195 $ function ();
181- } catch (Exception $ e ) {
182- Tools:: log ( ' cron ' )-> error ( $ e -> getMessage (), [
196+ } catch (Throwable $ e ) {
197+ $ logData = [
183198 'jobname ' => $ this ->jobname ,
184199 'pluginname ' => $ this ->pluginname ,
185- ]);
200+ ];
201+
202+ if ($ e instanceof Error) {
203+ $ logData ['type ' ] = 'fatal_error ' ;
204+ }
205+
206+ Tools::log ('cron ' )->critical ($ e ->getMessage (), $ logData );
207+
208+ $ start = $ this ->start ;
209+ $ this ->reload ();
210+ $ this ->start = $ start ;
186211
187212 $ this ->duration = round (microtime (true ) - $ this ->start , 5 );
188213 $ this ->done = true ;
189214 $ this ->failed = true ;
215+ $ this ->fails ++;
216+ $ this ->running --;
190217 $ this ->save ();
218+
191219 return false ;
192220 }
193221
222+ $ start = $ this ->start ;
223+ $ this ->reload ();
224+ $ this ->start = $ start ;
225+
194226 $ this ->duration = round (microtime (true ) - $ this ->start , 5 );
195227 $ this ->done = true ;
228+ $ this ->failed = false ;
229+ $ this ->running --;
196230 $ this ->save ();
231+
197232 return true ;
198233 }
199234
@@ -207,6 +242,12 @@ public function test(): bool
207242 $ this ->jobname = Tools::noHtml ($ this ->jobname );
208243 $ this ->pluginname = Tools::noHtml ($ this ->pluginname );
209244
245+ if ($ this ->running < 0 ) {
246+ $ this ->running = 0 ;
247+ } elseif ($ this ->running > 0 ) {
248+ $ this ->done = false ;
249+ }
250+
210251 return parent ::test ();
211252 }
212253
@@ -223,11 +264,9 @@ public function withoutOverlapping(...$jobs): self
223264 Where::eq ('enabled ' , true ),
224265 ];
225266
226- if (count ($ jobs ) > 0 ) {
227- $ whereRunning [] = Where::in ('jobname ' , $ jobs );
228- } else {
229- $ whereRunning [] = Where::notEq ('jobname ' , $ this ->jobname );
230- }
267+ $ whereRunning [] = count ($ jobs ) > 0 ?
268+ Where::in ('jobname ' , $ jobs ) :
269+ Where::notEq ('jobname ' , $ this ->jobname );
231270
232271 $ this ->overlapping = $ this ->count ($ whereRunning ) > 0 ;
233272
0 commit comments