Skip to content

Commit e6ef4e8

Browse files
author
Carlos Garcia
committed
Mejorada la gestión de cronjobs con contador de procesos, contador de fallos, duración de la anterior ejecución y mejoras en el manejo de errores.
1 parent 0209146 commit e6ef4e8

File tree

7 files changed

+109
-25
lines changed

7 files changed

+109
-25
lines changed

Core/Controller/Cron.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use FacturaScripts\Core\Kernel;
2626
use FacturaScripts\Core\Plugins;
2727
use FacturaScripts\Core\Tools;
28+
use FacturaScripts\Core\Where;
2829
use FacturaScripts\Core\WorkQueue;
2930
use FacturaScripts\Dinamic\Model\AlbaranCliente;
3031
use FacturaScripts\Dinamic\Model\AlbaranProveedor;
@@ -121,10 +122,10 @@ private function job(string $name): CronJob
121122
{
122123
$job = new CronJob();
123124
$where = [
124-
new DataBaseWhere('jobname', $name),
125-
new DataBaseWhere('pluginname', null, 'IS')
125+
Where::eq('jobname', $name),
126+
Where::isNull('pluginname')
126127
];
127-
if (false === $job->loadFromCode('', $where)) {
128+
if (false === $job->loadWhere($where)) {
128129
// no se había ejecutado nunca, lo creamos
129130
$job->jobname = $name;
130131
}

Core/Model/CronJob.php

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@
2020
namespace FacturaScripts\Core\Model;
2121

2222
use Closure;
23-
use Exception;
23+
use Error;
2424
use FacturaScripts\Core\Template\ModelClass;
2525
use FacturaScripts\Core\Template\ModelTrait;
2626
use FacturaScripts\Core\Tools;
2727
use 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

Core/Table/cronjobs.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<column>
1919
<name>duration</name>
2020
<type>double precision</type>
21+
<default>0</default>
2122
</column>
2223
<column>
2324
<name>enabled</name>
@@ -29,6 +30,11 @@
2930
<type>boolean</type>
3031
<default>false</default>
3132
</column>
33+
<column>
34+
<name>fails</name>
35+
<type>integer</type>
36+
<default>0</default>
37+
</column>
3238
<column>
3339
<name>id</name>
3440
<type>serial</type>
@@ -39,10 +45,20 @@
3945
<type>character varying(50)</type>
4046
<null>NO</null>
4147
</column>
48+
<column>
49+
<name>last_duration</name>
50+
<type>double precision</type>
51+
<default>0</default>
52+
</column>
4253
<column>
4354
<name>pluginname</name>
4455
<type>character varying(50)</type>
4556
</column>
57+
<column>
58+
<name>running</name>
59+
<type>integer</type>
60+
<default>0</default>
61+
</column>
4662
<constraint>
4763
<name>cronjobs_pkey</name>
4864
<type>PRIMARY KEY (id)</type>

Core/Template/CronClass.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
33
* This file is part of FacturaScripts
4-
* Copyright (C) 2023 Carlos Garcia Gomez <carlos@facturascripts.com>
4+
* Copyright (C) 2023-2025 Carlos Garcia Gomez <carlos@facturascripts.com>
55
*
66
* This program is free software: you can redistribute it and/or modify
77
* it under the terms of the GNU Lesser General Public License as
@@ -19,7 +19,7 @@
1919

2020
namespace FacturaScripts\Core\Template;
2121

22-
use FacturaScripts\Core\Base\DataBase\DataBaseWhere;
22+
use FacturaScripts\Core\Where;
2323
use FacturaScripts\Dinamic\Model\CronJob;
2424

2525
abstract class CronClass
@@ -38,10 +38,10 @@ protected function job(string $name): CronJob
3838
{
3939
$job = new CronJob();
4040
$where = [
41-
new DataBaseWhere('jobname', $name),
42-
new DataBaseWhere('pluginname', $this->pluginName)
41+
Where::eq('jobname', $name),
42+
Where::eq('pluginname', $this->pluginName)
4343
];
44-
if (false === $job->loadFromCode('', $where)) {
44+
if (false === $job->loadWhere($where)) {
4545
// no se había ejecutado nunca, lo creamos
4646
$job->jobname = $name;
4747
$job->pluginname = $this->pluginName;

Core/XMLView/EditCronJob.xml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
* This file is part of FacturaScripts
4-
* Copyright (C) 2019-2023 Carlos Garcia Gomez <carlos@facturascripts.com>
4+
* Copyright (C) 2019-2025 Carlos Garcia Gomez <carlos@facturascripts.com>
55
*
66
* This program is free software: you can redistribute it and/or modify
77
* it under the terms of the GNU Lesser General Public License as
@@ -39,12 +39,21 @@
3939
<column name="enabled" numcolumns="2" order="150">
4040
<widget type="checkbox" fieldname="enabled"/>
4141
</column>
42-
<column name="done" order="160">
42+
<column name="done" numcolumns="2" order="160">
4343
<widget type="checkbox" fieldname="done" readonly="true"/>
4444
</column>
45-
<column name="failed" order="170">
45+
<column name="failed" numcolumns="2" order="170">
4646
<widget type="checkbox" fieldname="failed" readonly="true"/>
4747
</column>
48+
<column name="running" numcolumns="2" order="180">
49+
<widget type="number" fieldname="running" readonly="true"/>
50+
</column>
51+
<column name="fails" numcolumns="2" order="190">
52+
<widget type="number" fieldname="fails" readonly="true"/>
53+
</column>
54+
<column name="last-duration" numcolumns="2" order="200">
55+
<widget type="number" fieldname="last_duration" icon="fa-solid fa-clock" readonly="true"/>
56+
</column>
4857
</group>
4958
</columns>
5059
</view>

Core/XMLView/ListCronJob.xml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
* This file is part of FacturaScripts
4-
* Copyright (C) 2017-2024 Carlos Garcia Gomez <carlos@facturascripts.com>
4+
* Copyright (C) 2017-2025 Carlos Garcia Gomez <carlos@facturascripts.com>
55
*
66
* This program is free software: you can redistribute it and/or modify
77
* it under the terms of the GNU Lesser General Public License as
@@ -33,18 +33,29 @@
3333
<column name="enabled" display="center" order="130">
3434
<widget type="checkbox" fieldname="enabled"/>
3535
</column>
36-
<column name="done" display="center" order="140">
36+
<column name="running" display="right" order="140">
37+
<widget type="number" fieldname="running" decimal="0"/>
38+
</column>
39+
<column name="done" display="left" order="150">
3740
<widget type="checkbox" fieldname="done"/>
3841
</column>
39-
<column name="failed" display="center" order="150">
42+
<column name="failed" display="right" order="160">
4043
<widget type="checkbox" fieldname="failed"/>
4144
</column>
42-
<column name="duration" display="right" order="160">
45+
<column name="fails" display="left" order="170">
46+
<widget type="number" fieldname="fails" decimal="0"/>
47+
</column>
48+
<column name="duration" display="right" order="180">
4349
<widget type="seconds" fieldname="duration">
4450
<option color="danger">gt:30</option>
4551
</widget>
4652
</column>
47-
<column name="date" display="right" order="170">
53+
<column name="last-duration" display="left" order="190">
54+
<widget type="seconds" fieldname="last_duration">
55+
<option color="danger">gt:30</option>
56+
</widget>
57+
</column>
58+
<column name="date" display="right" order="200">
4859
<widget type="datetime" fieldname="date"/>
4960
</column>
5061
</columns>

Test/Core/Model/CronJobTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@
2222
use Exception;
2323
use FacturaScripts\Core\Model\CronJob;
2424
use FacturaScripts\Core\Tools;
25+
use FacturaScripts\Test\Traits\LogErrorsTrait;
2526
use PHPUnit\Framework\TestCase;
2627

2728
final class CronJobTest extends TestCase
2829
{
30+
use LogErrorsTrait;
31+
2932
public function testCreate(): void
3033
{
3134
$job = new CronJob();
@@ -242,4 +245,9 @@ public function testWithoutOverlapping(): void
242245
$this->assertTrue($job1->delete());
243246
$this->assertTrue($job2->delete());
244247
}
248+
249+
protected function tearDown(): void
250+
{
251+
$this->logErrors();
252+
}
245253
}

0 commit comments

Comments
 (0)