Skip to content

Commit 982747e

Browse files
committed
Add source code
1 parent d5b6a4d commit 982747e

18 files changed

+664
-5
lines changed

.gitignore

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
composer.phar
2+
composer.lock
23
/vendor/
3-
4-
# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
5-
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
6-
# composer.lock
4+
.phpunit.result.cache

.scrutinizer.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
checks:
2+
php:
3+
code_rating: true
4+
duplication: true
5+
6+
build:
7+
tests:
8+
override:
9+
- command: 'phpunit --coverage-clover=clover.xml'
10+
coverage:
11+
file: 'clover.xml'
12+
format: 'clover'

.travis.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
language: php
2+
3+
php:
4+
- 7.2
5+
- 7.3
6+
- 7.4snapshot
7+
8+
matrix:
9+
allow_failures:
10+
- php: 7.4snapshot
11+
12+
before_script:
13+
- composer selfupdate
14+
- composer install --prefer-dist
15+
16+
notifications:
17+
email: false

README.md

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,112 @@
1-
# task-manager-lib
1+
[![Build Status](https://travis-ci.org/cgauge/task-manager-lib.svg?branch=master)](https://travis-ci.org/cgauge/task-manager-lib)
2+
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/cgauge/task-manager-lib/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/cgauge/task-manager-lib/?branch=master)
3+
4+
# Task Manager ⚙️
5+
6+
# Installation
7+
8+
```bash
9+
composer require customergauge/task-manager
10+
```
11+
# Usage
12+
13+
## Execute a task
14+
15+
```php
16+
use Customergauge\TaskManager\Task;
17+
use Customergauge\TaskManager\TaskManager;
18+
19+
class SimpleTask implements Task
20+
{
21+
public function run(array $attributes) : array
22+
{
23+
echo "simple task";
24+
}
25+
}
26+
27+
$taskManager = new TaskManager; // defaults to StopOnFailure strategy
28+
$taskManager->add(new SimpleTask);
29+
30+
$taskManager->run([]);
31+
32+
// output: simple task
33+
```
34+
## Continue on failure strategy
35+
36+
```php
37+
use Customergauge\TaskManager\Task;
38+
use Customergauge\TaskManager\TaskManager;
39+
use Customergauge\TaskManager\Strategy\ContinueOnFailure;
40+
41+
class FirstTask implements Task
42+
{
43+
public function run(array $attributes) : array
44+
{
45+
throw new Exception;
46+
}
47+
}
48+
49+
class SecondTask implements Task
50+
{
51+
public function run(array $attributes) : array
52+
{
53+
echo "second task";
54+
}
55+
}
56+
57+
$taskManager = new TaskManager(new ContinueOnFailure);
58+
$taskManager->add(new FirstTask)
59+
->add(new SecondTask)
60+
61+
$taskManager->run([]);
62+
63+
// output: second task
64+
```
65+
66+
## Rollback executed tasks
67+
68+
```php
69+
use Customergauge\TaskManager\Task;
70+
use Customergauge\TaskManager\Reversible;
71+
use Customergauge\TaskManager\TaskManager;
72+
use Customergauge\TaskManager\Strategy\RollbackOnFailure;
73+
74+
class FirstTask implements Task, Reversible
75+
{
76+
public function run(array $attributes) : array
77+
{
78+
echo "first task";
79+
}
80+
81+
public function reverse(array $attributes)
82+
{
83+
echo "reverse first task";
84+
}
85+
}
86+
87+
class SecondTask implements Task
88+
{
89+
public function run(array $attributes) : array
90+
{
91+
throw new Exception;
92+
}
93+
}
94+
95+
$taskManager = new TaskManager(new RollbackOnFailure);
96+
$taskManager->add(new FirstTask)
97+
->add(new SecondTask)
98+
99+
$taskManager->run([]);
100+
101+
// output:
102+
firt task
103+
reverse first task
104+
```
105+
106+
# Contributing
107+
108+
Contributions are always welcome, please have a look at our issues to see if there's something you could help with.
109+
110+
# License
111+
112+
Task Manager is licensed under MIT license.

composer.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "customergauge/task-manager",
3+
"type": "library",
4+
"license": "MIT",
5+
"authors": [
6+
{
7+
"name": "Abdala Cerqueira",
8+
"email": "[email protected]"
9+
}
10+
],
11+
"require": {
12+
"php": "^7.2",
13+
"psr/log": "^1.1"
14+
},
15+
"require-dev": {
16+
"phpunit/phpunit": "^8.0",
17+
"doctrine/coding-standard": "^6.0",
18+
"phpstan/phpstan": "^0.11.8"
19+
},
20+
"autoload": {
21+
"psr-4": {
22+
"CustomerGauge\\TaskManager\\": "src/"
23+
}
24+
},
25+
"autoload-dev": {
26+
"psr-4": {
27+
"Test\\CustomerGauge\\TaskManager\\": "tests/"
28+
}
29+
}
30+
}

phpunit.xml.dist

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false">
11+
<testsuites>
12+
<testsuite name="Unit Tests">
13+
<directory suffix="Test.php">./tests</directory>
14+
</testsuite>
15+
</testsuites>
16+
<filter>
17+
<whitelist processUncoveredFilesFromWhitelist="true">
18+
<directory suffix=".php">./src</directory>
19+
</whitelist>
20+
</filter>
21+
</phpunit>

src/InvalidTaskAttribute.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CustomerGauge\TaskManager;
6+
7+
use InvalidArgumentException;
8+
use function get_class;
9+
use function implode;
10+
use function sprintf;
11+
12+
class InvalidTaskAttribute extends InvalidArgumentException
13+
{
14+
/**
15+
* @param array<int, int|string> $keys
16+
*/
17+
public static function duplicatedKey(Task $task, array $keys) : self
18+
{
19+
$message = sprintf(
20+
'Duplicate task [%s] attribute keys [%s]. Use a different attribute key.',
21+
get_class($task),
22+
implode(', ', $keys)
23+
);
24+
25+
return new static($message);
26+
}
27+
}

src/Reversible.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CustomerGauge\TaskManager;
6+
7+
interface Reversible
8+
{
9+
/**
10+
* @param mixed[] $attributes
11+
*/
12+
public function reverse(array $attributes) : void;
13+
}

src/Strategy/ContinueOnFailure.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CustomerGauge\TaskManager\Strategy;
6+
7+
use Throwable;
8+
9+
class ContinueOnFailure implements Strategy
10+
{
11+
/** @var Throwable[] */
12+
private $exceptions = [];
13+
14+
/**
15+
* @param mixed[] $context
16+
*/
17+
public function execute(callable $callback, array $context = []) : void
18+
{
19+
try {
20+
$callback();
21+
} catch (Throwable $e) {
22+
$this->exceptions[] = $e;
23+
}
24+
}
25+
26+
/**
27+
* @return Throwable[]
28+
*/
29+
public function exceptions() : array
30+
{
31+
return $this->exceptions;
32+
}
33+
}

src/Strategy/RollbackOnFailure.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace CustomerGauge\TaskManager\Strategy;
6+
7+
use CustomerGauge\TaskManager\Reversible;
8+
use CustomerGauge\TaskManager\Task;
9+
use Throwable;
10+
use function array_filter;
11+
use function array_unshift;
12+
13+
class RollbackOnFailure implements Strategy
14+
{
15+
/** @var Task[] */
16+
private $executed = [];
17+
18+
/** @var mixed[] */
19+
private $context;
20+
21+
/**
22+
* @param mixed[] $context
23+
*/
24+
public function execute(callable $callback, array $context = []) : void
25+
{
26+
$this->context = $context;
27+
28+
try {
29+
$task = $callback();
30+
31+
array_unshift($this->executed, $task);
32+
} catch (Throwable $e) {
33+
$this->rollback();
34+
}
35+
}
36+
37+
public function rollback() : void
38+
{
39+
$tasks = array_filter($this->executed, static function ($task) : bool {
40+
return $task instanceof Reversible;
41+
});
42+
43+
foreach ($tasks as $task) {
44+
$task->reverse($this->context);
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)