Skip to content

Commit 62c71a2

Browse files
authored
feat(crontab): add database-based crontab configuration and execution (#151)
* feat(crontab): add database-based crontab configuration and execution - Implement database-driven crontab configuration with migrations - Add Crontab, Schedule, and CrontabContainer classes for task management - Include CrontabUrl for URL-based task execution - Add CI workflows for pull request handling and releases - Implement logging and aspect-oriented execution tracking - Add comprehensive test coverage for all components * feat(Crontab): add serialization methods for cronId Add __serialize and __unserialize methods to handle cronId property during serialization. Also reorganize composer.json dependencies alphabetically for better maintainability. * refactor(tests): move Crontab test files to new directory structure Restructure test files for Crontab component by moving them from src/Crontab/tests to tests/Crontab directory. This includes test cases for ConfigProvider, CrontabContainer, CrontabUrl, CrontabProcessStarredListener, Schedule, CrontabExecutorAspect, and Crontab classes. The changes maintain all existing test functionality while improving project organization.
0 parents  commit 62c71a2

16 files changed

Lines changed: 615 additions & 0 deletions

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/tests export-ignore
2+
/.github export-ignore
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Close Pull Request
2+
3+
permissions: write-all
4+
5+
on:
6+
pull_request_target:
7+
types: [ opened ]
8+
9+
jobs:
10+
run:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: superbrothers/close-pull-request@v3
14+
with:
15+
comment: "Hi, this is a READ-ONLY repository, please submit your PR on the https://github.com/mineadmin/components repository.<br><br> This Pull Request will close automatically.<br><br> Thanks! "

.github/workflows/release.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
on:
2+
push:
3+
tags:
4+
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
5+
6+
name: Release
7+
permissions: write-all
8+
9+
jobs:
10+
release:
11+
name: Release
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v4
16+
- name: Create Release
17+
id: create_release
18+
uses: actions/create-release@v1
19+
env:
20+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21+
with:
22+
tag_name: ${{ github.ref }}
23+
release_name: Release ${{ github.ref }}
24+
draft: false
25+
prerelease: false
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of MineAdmin.
6+
*
7+
* @link https://www.mineadmin.com
8+
* @document https://doc.mineadmin.com
9+
* @contact root@imoi.cn
10+
* @license https://github.com/mineadmin/MineAdmin/blob/master/LICENSE
11+
*/
12+
use Hyperf\Database\Migrations\Migration;
13+
use Hyperf\Database\Schema\Blueprint;
14+
use Hyperf\Database\Schema\Schema;
15+
16+
class CreateCrontab extends Migration
17+
{
18+
/**
19+
* Run the migrations.
20+
*/
21+
public function up(): void
22+
{
23+
Schema::create('crontab', static function (Blueprint $table) {
24+
$table->bigIncrements('id');
25+
/*
26+
* name string 30
27+
* status tinyint 1 default 0
28+
* memo string 60 default null
29+
* type string 10 not null
30+
* value string longtext not null
31+
*/
32+
$table->string('name', 30);
33+
$table->tinyInteger('status')->default(0);
34+
$table->tinyInteger('is_on_one_server')->default(0);
35+
$table->tinyInteger('is_singleton')->default(0);
36+
$table->string('memo', 60)->default(null);
37+
$table->string('type', 10);
38+
$table->string('rule', 30);
39+
$table->text('value');
40+
$table->datetimes();
41+
});
42+
}
43+
44+
/**
45+
* Reverse the migrations.
46+
*/
47+
public function down(): void
48+
{
49+
Schema::dropIfExists('crontab');
50+
}
51+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of MineAdmin.
6+
*
7+
* @link https://www.mineadmin.com
8+
* @document https://doc.mineadmin.com
9+
* @contact root@imoi.cn
10+
* @license https://github.com/mineadmin/MineAdmin/blob/master/LICENSE
11+
*/
12+
use Hyperf\Database\Migrations\Migration;
13+
use Hyperf\Database\Schema\Blueprint;
14+
use Hyperf\Database\Schema\Schema;
15+
16+
class CreateCrontabExecuteLog extends Migration
17+
{
18+
/**
19+
* Run the migrations.
20+
*/
21+
public function up(): void
22+
{
23+
Schema::create('crontab_execute_log', static function (Blueprint $table) {
24+
$table->bigIncrements('id');
25+
$table->bigInteger('crontab_id');
26+
$table->string('name', 100);
27+
$table->tinyInteger('status')->default(0);
28+
$table->string('target', 200);
29+
$table->text('exception_info');
30+
$table->datetimes();
31+
});
32+
}
33+
34+
/**
35+
* Reverse the migrations.
36+
*/
37+
public function down(): void
38+
{
39+
Schema::dropIfExists('crontab_execute_log');
40+
}
41+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 MineAdmin
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Hyperf Crontab 加强
2+
3+
在原有的基础上增加了定时任务从数据库读取的配置

composer.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "mineadmin/crontab",
3+
"description": "加强 Hyperf Crontab",
4+
"license": "MIT",
5+
"type": "library",
6+
"authors": [
7+
{
8+
"name": "x.mo",
9+
"role": "Developer"
10+
},
11+
{
12+
"name": "zds",
13+
"role": "Developer"
14+
}
15+
],
16+
"require": {
17+
"php": ">=8.1",
18+
"hyperf/crontab": "^3.1",
19+
"hyperf/database": "^3.1",
20+
"hyperf/db-connection": "^3.1"
21+
},
22+
"autoload": {
23+
"psr-4": {
24+
"Mine\\Crontab\\": "src/"
25+
}
26+
},
27+
"autoload-dev": {
28+
"psr-4": {
29+
"Mine\\Crontab\\Tests\\": "tests/"
30+
}
31+
},
32+
"extra": {
33+
"hyperf": {
34+
"config": "Mine\\Crontab\\ConfigProvider"
35+
}
36+
}
37+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of MineAdmin.
6+
*
7+
* @link https://www.mineadmin.com
8+
* @document https://doc.mineadmin.com
9+
* @contact root@imoi.cn
10+
* @license https://github.com/mineadmin/MineAdmin/blob/master/LICENSE
11+
*/
12+
13+
namespace Mine\Crontab\Aspect;
14+
15+
use Hyperf\Crontab\Crontab;
16+
use Hyperf\Crontab\Strategy\Executor;
17+
use Hyperf\DbConnection\Db;
18+
use Hyperf\Di\Aop\AbstractAspect;
19+
use Hyperf\Di\Aop\ProceedingJoinPoint;
20+
use Mine\Crontab\CrontabContainer;
21+
22+
class CrontabExecutorAspect extends AbstractAspect
23+
{
24+
public array $classes = [
25+
Executor::class . '::logResult',
26+
];
27+
28+
public function process(ProceedingJoinPoint $proceedingJoinPoint)
29+
{
30+
/**
31+
* @var Crontab $crontab
32+
* @var bool $isSuccess
33+
* @var null|\Throwable $throwable
34+
*/
35+
[$crontab, $isSuccess, $throwable] = $proceedingJoinPoint->getArguments();
36+
if ($crontab instanceof \Mine\Crontab\Crontab) {
37+
$callback = $crontab->getCallback();
38+
if (\is_array($callback)) {
39+
$callback = json_encode($callback, \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_UNICODE);
40+
}
41+
Db::connection(CrontabContainer::$connectionName)
42+
->table('crontab_execute_log')
43+
->insert([
44+
'crontab_id' => $crontab->getCronId(),
45+
'name' => $crontab->getName(),
46+
'target' => $callback,
47+
'status' => $isSuccess ? 1 : 0,
48+
'exception_info' => $throwable === null ? '' : $throwable->getMessage(),
49+
]);
50+
}
51+
return $proceedingJoinPoint->process();
52+
}
53+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of MineAdmin.
6+
*
7+
* @link https://www.mineadmin.com
8+
* @document https://doc.mineadmin.com
9+
* @contact root@imoi.cn
10+
* @license https://github.com/mineadmin/MineAdmin/blob/master/LICENSE
11+
*/
12+
13+
namespace Mine\Crontab\Command;
14+
15+
use Hyperf\Command\Command as Base;
16+
use Hyperf\Database\Migrations\Migrator;
17+
use Symfony\Component\Console\Input\InputOption;
18+
use Symfony\Component\Console\Output\NullOutput;
19+
20+
class CrontabMigrateCommand extends Base
21+
{
22+
protected ?string $name = 'crontab:migrate';
23+
24+
public function __construct(
25+
private readonly Migrator $migrator
26+
) {
27+
parent::__construct();
28+
}
29+
30+
public function __invoke()
31+
{
32+
$connection = $this->input->getOption('connection');
33+
if (empty($connection)) {
34+
$connection = 'default';
35+
}
36+
$migrator = $this->migrator;
37+
$migrator->setConnection($connection);
38+
$this->migrator
39+
->setOutput(new NullOutput())
40+
->run(\dirname(__DIR__, 2) . '/Database/Migrations');
41+
}
42+
43+
protected function getOptions(): array
44+
{
45+
return [
46+
new InputOption('connection', 'connection', InputOption::VALUE_OPTIONAL, 'connection name'),
47+
];
48+
}
49+
}

0 commit comments

Comments
 (0)