This commit is contained in:
2021-08-25 19:11:15 +08:00
parent 84703373a2
commit bd1f60623e
22 changed files with 689 additions and 975 deletions
+7 -2
View File
@@ -19,7 +19,6 @@
"ext-iconv": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"ext-inotify": "*",
"ext-curl": "*",
"ext-openssl": "*",
"amphp/amp": "v1.2.2",
@@ -30,7 +29,13 @@
"ext-rdkafka": "*",
"ext-gd": "*",
"swiftmailer/swiftmailer": "^6.0",
"ext-spltype": "*"
"psr/container": "^2.0",
"psr/http-server-middleware": "^1.0",
"psr/link": "^2.0",
"psr/cache": "^3.0",
"psr/http-client": "^1.0",
"psr/simple-cache": "^1.0",
"game-worker/kiri-event": "dev-master"
},
"autoload": {
"psr-4": {
-292
View File
@@ -1,292 +0,0 @@
<?php
namespace Kiri\Crontab;
use Exception;
use JetBrains\PhpStorm\Pure;
use Server\SInterface\PipeMessage;
use Kiri\Application;
use Kiri\Kiri;
use Swoole\Timer;
/**
* Class Async
* @package Kiri
* @property Application $application
*/
abstract class Crontab implements PipeMessage, CrontabInterface
{
const WAIT_END = 'crontab:wait:execute';
private string $name = '';
private mixed $params;
private int $tickTime;
private bool $isLoop;
private int $timerId = -1;
private int $max_execute_number = -1;
private int $execute_number = 0;
/**
* Crontab constructor.
* @param mixed $params
* @param false $isLoop
* @param int $tickTime
*/
public function __construct(mixed $params, bool $isLoop = false, int $tickTime = 1)
{
$this->params = $params;
$this->isLoop = $isLoop;
$this->tickTime = $tickTime;
}
/**
* @return Application
*/
#[Pure] private function getApplication(): Application
{
return Kiri::app();
}
/**
* @return $this
*/
public function increment(): static
{
$this->execute_number += 1;
return $this;
}
/**
* @return string
*/
#[Pure] public function getName(): string
{
return md5($this->name);
}
/**
* @return mixed
*/
public function getParams(): mixed
{
return $this->params;
}
/**
* @return int
*/
public function getTickTime(): int
{
return $this->tickTime;
}
/**
* @return bool
*/
public function isLoop(): bool
{
return $this->isLoop;
}
/**
* @return int
*/
public function getMaxExecuteNumber(): int
{
return $this->max_execute_number;
}
/**
* @return int
*/
public function getExecuteNumber(): int
{
return $this->execute_number;
}
/**
* @param string $name
*/
public function setName(string $name): void
{
$this->name = $name;
}
/**
* @param int $max_execute_number
*/
public function setMaxExecuteNumber(int $max_execute_number): void
{
$this->max_execute_number = $max_execute_number;
}
/**
* @param int $execute_number
*/
public function setExecuteNumber(int $execute_number): void
{
$this->execute_number = $execute_number;
}
/**
* @return int
*/
public function getTimerId(): int
{
return $this->timerId;
}
/**
*
* @throws Exception
*/
public function clearTimer()
{
$this->application->warning('crontab timer clear.');
if (Timer::exists($this->timerId)) {
Timer::clear($this->timerId);
}
}
/**
* @param $name
* @return mixed
*/
#[Pure] public function __get($name): mixed
{
if ($name === 'application') {
return $this->getApplication();
}
if (!isset($this->params[$name])) {
return null;
}
return $this->params[$name];
}
/**
* @throws Exception
*/
public function execute(): void
{
try {
defer(fn() => $this->afterExecute());
$redis = $this->application->getRedis();
$name_md5 = $this->getName();
$redis->hSet(self::WAIT_END, $name_md5, static::getSerialize($this));
call_user_func([$this, 'process']);
$this->execute_number += 1;
$redis->hDel(self::WAIT_END, $name_md5);
} catch (\Throwable $throwable) {
$this->application->addError($throwable, 'throwable');
}
}
/**
* @throws Exception
*/
public function afterExecute()
{
if ($this->isRecover() !== 999) {
return;
}
$redis = $this->application->getRedis();
$name = $this->getName();
if (!$redis->exists('stop:crontab:' . $name)) {
$redis->set('crontab:' . $name, swoole_serialize($this));
$tickTime = time() + $this->getTickTime();
$redis->zAdd(Producer::CRONTAB_KEY, $tickTime, $name);
} else {
$redis->del('crontab:' . $name);
$redis->del('stop:crontab:' . $name);
}
}
/**
* @return bool|int
* @throws Exception
*/
public function isRecover(): bool|int
{
try {
$redis = $this->application->getRedis();
$crontab_name = $this->getName();
if ($redis->exists('stop:crontab:' . $crontab_name)) {
return $redis->del('stop:crontab:' . $crontab_name);
}
if ($this->isExit()) {
return $redis->del('crontab:' . $crontab_name);
}
if (!$this->isMaxExecute()) {
return 999;
}
call_user_func([$this, 'onMaxExecute']);
return $redis->del('crontab:' . $crontab_name);
} catch (\Throwable $throwable) {
return $this->application->addError($throwable, 'throwable');
}
}
/**
* @param $class
* @return string
*/
public static function getSerialize($class): string
{
return serialize($class);
}
/**
* @return bool
*/
private function isExit(): bool
{
if ($this->isStop() || !$this->isLoop) {
return true;
}
return false;
}
/**
* @return bool
*/
private function isMaxExecute(): bool
{
if ($this->max_execute_number !== -1) {
return $this->execute_number >= $this->max_execute_number;
}
return false;
}
}
-20
View File
@@ -1,20 +0,0 @@
<?php
namespace Kiri\Crontab;
interface CrontabInterface
{
/**
*
*/
public function onMaxExecute(): void;
/**
* @return bool
*/
public function isStop(): bool;
}
-40
View File
@@ -1,40 +0,0 @@
<?php
namespace Kiri\Crontab;
use Exception;
use ReflectionException;
use Kiri\Abstracts\Config;
use Kiri\Abstracts\Providers;
use Kiri\Application;
use Kiri\Exception\ComponentException;
use Kiri\Exception\ConfigException;
use Kiri\Exception\NotFindClassException;
/**
* Class CrontabProviders
* @package Kiri\Crontab
*/
class CrontabProviders extends Providers
{
/**
* @param Application $application
* @throws ConfigException
* @throws Exception
*/
public function onImport(Application $application)
{
$server = $application->getServer();
$application->set('crontab', ['class' => Producer::class]);
if (Config::get('crontab.enable') !== true) {
return;
}
$server->addProcess(Zookeeper::class);
}
}
-40
View File
@@ -1,40 +0,0 @@
<?php
namespace Kiri\Crontab;
/**
* Class DefaultCrontab
* @package Kiri\Crontab
*/
class DefaultCrontab extends Crontab
{
/**
* @return bool
*/
public function isStop(): bool
{
return true;
}
/**
*
*/
public function process(): void
{
// TODO: Implement process() method.
}
/**
*
*/
public function onMaxExecute(): void
{
// TODO: Implement max_execute() method.
}
}
-96
View File
@@ -1,96 +0,0 @@
<?php
namespace Kiri\Crontab;
use Exception;
use Kiri\Abstracts\Component;
use Kiri\Kiri;
/**
* Class Producer
* @package Kiri\Abstracts
*/
class Producer extends Component
{
const CRONTAB_KEY = '_application:{crontab}:system:crontab';
/**
* @param Crontab $crontab
* @throws Exception
*/
public function dispatch(Crontab $crontab)
{
$redis = Kiri::app()->getRedis();
$name = $crontab->getName();
if ($redis->exists(self::CRONTAB_KEY) && $redis->type(self::CRONTAB_KEY) !== \Redis::REDIS_ZSET) {
throw new Exception('Cache key ' . self::CRONTAB_KEY . ' types error.');
}
$redis->del('stop:crontab:' . $name);
$redis->del('crontab:' . $name);
$redis->zRem(static::CRONTAB_KEY, $name);
$redis->zAdd(self::CRONTAB_KEY, time() + $crontab->getTickTime(), $name);
$redis->set('crontab:' . $name, swoole_serialize($crontab));
}
/**
* @param string $name
* @throws Exception
*/
public function clear(string $name)
{
$redis = Kiri::app()->getRedis();
$redis->del('crontab:' . md5($name));
$redis->zRem(static::CRONTAB_KEY, md5($name));
$redis->setex('stop:crontab:' . md5($name), 120, 1);
}
/**
* @param string $name
* @return bool
* @throws Exception
*/
public function exists(string $name): bool
{
$redis = Kiri::app()->getRedis();
if ($redis->exists('crontab:' . md5($name))) {
return true;
}
if ($redis->zRank(static::CRONTAB_KEY, md5($name))) {
return true;
}
if ($redis->hExists(Crontab::WAIT_END, md5($name))) {
return true;
}
return false;
}
/**
* @throws Exception
*/
public function clearAll()
{
$redis = Kiri::app()->getRedis();
$data = $redis->zRange(self::CRONTAB_KEY, 0, -1);
foreach ($data as $datum) {
$redis->setex('stop:crontab:' . $datum, 120, 1);
$redis->del('crontab:' . $datum);
}
$redis->release();
}
}
-129
View File
@@ -1,129 +0,0 @@
<?php
namespace Kiri\Crontab;
use Exception;
use Kiri\Abstracts\Config;
use Kiri\Cache\Redis;
use Kiri\Exception\ConfigException;
use Kiri\Kiri;
use Server\Abstracts\CustomProcess;
use Server\ServerManager;
use Swoole\Process;
use Swoole\Timer;
use Throwable;
/**
* Class Zookeeper
* @package Kiri\Process
*/
class Zookeeper extends CustomProcess
{
private int $workerNum = 0;
private int $_timer = -1;
/**
* @param Process $process
* @return string
* @throws ConfigException
*/
public function getProcessName(Process $process): string
{
$name = Config::get('id', 'system') . '[' . $process->pid . ']';
if (!empty($prefix)) {
$name .= '.Crontab zookeeper';
}
return $name;
}
/**
* @param Process $process
* @throws Exception
*/
public function onHandler(Process $process): void
{
$this->_timer = Timer::tick(300, [$this, 'loop']);
}
/**
* @throws ConfigException
* @throws Exception
*/
public function loop()
{
if ($this->checkProcessIsStop()) {
$this->exit();
Timer::clear($this->_timer);
return;
}
$redis = Kiri::app()->getRedis();
defer(fn() => $redis->release());
$range = $this->loadCarobTask($redis);
foreach ($range as $value) {
$this->dispatch($redis, $value);
}
}
/**
* @param Redis|\Redis $redis
* @param $value
* @throws Exception
*/
private function dispatch(Redis|\Redis $redis, $value)
{
try {
if (empty($handler = $redis->get('crontab:' . $value))) {
return;
}
$server = di(ServerManager::class)->getServer();
$server->sendMessage(swoole_unserialize($handler), $this->getWorker());
} catch (Throwable $exception) {
logger()->addError($exception);
}
}
/**
* @return int
* @throws Exception
*/
private function getWorker(): int
{
if ($this->workerNum == 0) {
$server = di(ServerManager::class)->getServer();
$this->workerNum = $server->setting['worker_num'] + ($server->setting['task_worker_num'] ?? 0);
}
return random_int(0, $this->workerNum - 1);
}
/**
* @param Redis|\Redis $redis
* @return array
*/
private function loadCarobTask(Redis|\Redis $redis): array
{
$script = <<<SCRIPT
local _two = redis.call('zRangeByScore', KEYS[1], '0', ARGV[1])
if (table.getn(_two) > 0) then
redis.call('ZREM', KEYS[1], unpack(_two))
end
return _two
SCRIPT;
return $redis->eval($script, [Producer::CRONTAB_KEY, (string)time()], 1);
}
}
-37
View File
@@ -1,37 +0,0 @@
<?php
namespace Kiri\Events;
use Annotation\Inject;
use Kiri\Abstracts\BaseObject;
/**
*
*/
class EventDispatch extends BaseObject
{
#[Inject(EventProvider::class)]
public EventProvider $eventProvider;
/**
* @param object $triggerEvent
* @return object
*/
public function dispatch(object $triggerEvent): object
{
$lists = $this->eventProvider->getListenersForEvent($triggerEvent);
foreach ($lists as $listener) {
/** @var Struct $list */
$listener($triggerEvent);
if ($triggerEvent instanceof StoppableEventInterface && $triggerEvent->isPropagationStopped()) {
break;
}
}
return $triggerEvent;
}
}
-16
View File
@@ -1,16 +0,0 @@
<?php
namespace Kiri\Events;
/**
*
*/
interface EventInterface
{
public function process(): void;
}
-42
View File
@@ -1,42 +0,0 @@
<?php
namespace Kiri\Events;
/**
*
*/
class EventProvider implements EventProviders
{
/** @var Struct[] */
private array $_listeners = [];
/**
* @param object $event
* @return iterable
*/
public function getListenersForEvent(object $event): iterable
{
$queue = new \SplPriorityQueue();
// TODO: Implement getListenersForEvent() method.
foreach ($this->_listeners[get_class($event)] ?? [] as $listener) {
$queue->insert($listener->listener, $listener->priority);
}
return $queue;
}
/**
* @param string $event
* @param callable $handler
* @param int $zOrder
*/
public function on(string $event, callable $handler, int $zOrder = 1)
{
$this->_listeners[$event][] = new Struct($event, $handler, $zOrder);
}
}
-22
View File
@@ -1,22 +0,0 @@
<?php
namespace Kiri\Events;
/**
*
*/
interface EventProviders
{
/**
* @param object $event
* An event for which to return the relevant listeners.
* @return iterable<callable>
* An iterable (array, iterator, or generator) of callables. Each
* callable MUST be type-compatible with $event.
*/
public function getListenersForEvent(object $event): iterable;
}
-24
View File
@@ -1,24 +0,0 @@
<?php
namespace Kiri\Events;
/**
*
*/
interface StoppableEventInterface
{
/**
* Is propagation stopped?
*
* This will typically only be used by the Dispatcher to determine if the
* previous listener halted propagation.
*
* @return bool
* True if the Event is complete and no further listeners should be called.
* False to continue calling listeners.
*/
public function isPropagationStopped() : bool;
}
-25
View File
@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace Kiri\Events;
/**
*
*/
class Struct
{
public string $event;
public array|\Closure $listener;
public int $priority;
public function __construct(string $event, callable $listener, int $priority)
{
$this->event = $event;
$this->listener = $listener;
$this->priority = $priority;
}
}
+34
View File
@@ -0,0 +1,34 @@
# Created by .ignore support plugin (hsz.mobi)
### Yii template
assets/*
!assets/.gitignore
protected/runtime/*
!protected/runtime/.gitignore
protected/data/*.db
themes/classic/views/
### Example user template template
### Example user template
# IntelliJ project files
.idea
*.iml
out
gen
composer.lock
*.log
commands/result
config/setting.php
tests/
vendor/
runtime/
*.xml
*.lock
oot
d
composer.lock
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace PHPSTORM_META {
// Reflect
use Http\Context\Context;
use Kiri\Di\Container;
override(Container::get(0), map('@'));
override(Container::newObject(0), map('@'));
// override(\Hyperf\Utils\Context::get(0), map('@'));
// override(\make(0), map('@'));
override(\di(0), map('@'));
override(\duplicate(0), map('@'));
override(Context::getContext(0), map('@'));
}
+24
View File
@@ -0,0 +1,24 @@
{
"name": "game-worker/http-message",
"description": "db",
"authors": [
{
"name": "XiangLin",
"email": "as2252258@163.com"
}
],
"license": "MIT",
"require": {
"php": ">=8.0",
"ext-json": "*",
"psr/http-message": "^1.0"
},
"autoload": {
"psr-4": {
"HttpMessage\\": "src/"
}
},
"require-dev": {
"kwn/php-rdkafka-stubs": "^2.0"
}
}
+179
View File
@@ -0,0 +1,179 @@
<?php
namespace HttpMessage;
use Http\Context\Context;
use Kiri\Di\ContainerInterface;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\StreamInterface;
use Server\RequestInterface;
/**
*
*/
trait Message
{
/**
* @var string
*/
public string $protocol = '1.1';
/**
* @var mixed|string
*/
public mixed $body = '';
/**
* @var array<string,array>
*/
public array $headers = [];
/**
* @return string
*/
public function getProtocolVersion(): string
{
return $this->protocol;
}
/**
* @param string $version
* @return $this
*/
public function withProtocolVersion($version): static
{
// TODO: Implement withProtocolVersion() method.
$new = clone $this;
$new->protocol = $version;
return $new;
}
/**
* @return array
*/
public function getHeaders(): array
{
// TODO: Implement getHeaders() method.
return $this->headers;
}
/**
* @param string $name
* @return bool
*/
public function hasHeader($name): bool
{
// TODO: Implement hasHeader() method.
return isset($this->headers[$name]);
}
/**
* @param string $name
* @return mixed
*/
public function getHeader($name): mixed
{
// TODO: Implement getHeader() method.
if (!$this->hasHeader($name)) {
return null;
}
return $this->headers[$name];
}
/**
* @param string $name
* @return string|null
*/
public function getHeaderLine($name): ?string
{
// TODO: Implement getHeaderLine() method.
// TODO: Implement getHeader() method.
if (!$this->hasHeader($name)) {
return null;
}
return $this->headers[$name];
}
/**
* @param string $name
* @param string|string[] $value
* @return Message
*/
public function withHeader($name, $value): static
{
// TODO: Implement withHeader() method.
$newInstance = clone $this;
$newInstance->headers[$name] = [$value];
return $newInstance;
}
/**
* @param string $name
* @param string|string[] $value
* @return $this
*/
public function withAddedHeader($name, $value): static
{
// TODO: Implement withAddedHeader() method.
// TODO: Implement withHeader() method.
$newInstance = clone $this;
if (!isset($newInstance->headers)) {
$newInstance->headers[$name] = [$value];
} else {
$newInstance->headers[$name][] = $value;
}
return $newInstance;
}
/**
* @param string $name
* @return $this
*/
public function withoutHeader($name): static
{
// TODO: Implement withoutHeader() method.
$newInstance = clone $this;
if (!isset($newInstance->headers)) {
return $newInstance;
}
unset($newInstance->headers[$name]);
return $newInstance;
}
/**
* @return mixed
*/
public function getBody(): mixed
{
// TODO: Implement getBody() method.
return $this->body;
}
/**
* @param StreamInterface $body
* @return $this
*/
public function withBody(StreamInterface $body): static
{
// TODO: Implement withBody() method.
$newInstance = clone $this;
$newInstance->body = $body;
return $newInstance;
}
}
+113
View File
@@ -0,0 +1,113 @@
<?php
namespace HttpMessage;
use Annotation\Inject;
use JetBrains\PhpStorm\Pure;
use Kiri\Di\ContainerInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\UriInterface;
/**
*
*/
class Request implements RequestInterface
{
use Message;
public string $method;
public mixed $requestTarget;
/**
* @var UriInterface
*/
#[Inject(UriInterface::class)]
public UriInterface $uri;
/**
* @param ContainerInterface $container
*/
public function __construct(public ContainerInterface $container)
{
}
/**
* @return mixed
*/
public function getRequestTarget(): mixed
{
// TODO: Implement getRequestTarget() method.
return $this->requestTarget;
}
/**
* @param mixed $requestTarget
* @return Request
*/
public function withRequestTarget($requestTarget): static
{
// TODO: Implement withRequestTarget() method.
$newInstance = clone $this;
$newInstance->requestTarget = $requestTarget;
return $newInstance;
}
/**
* @return string
*/
public function getMethod(): string
{
// TODO: Implement getMethod() method.
return $this->method;
}
/**
* @param string $method
* @return $this
*/
public function withMethod($method): static
{
// TODO: Implement withMethod() method.
$newInstance = clone $this;
$newInstance->method = $method;
return $newInstance;
}
/**
* @return string
*/
#[Pure] public function getUri(): string
{
// TODO: Implement getUri() method.
$uri = $this->uri->getPath();
if (!empty($this->uri->getQuery())) {
$uri .= '?' . $this->uri->getQuery();
}
return $uri;
}
/**
* @param UriInterface $uri
* @param false $preserveHost
* @return Request
*/
public function withUri(UriInterface $uri, $preserveHost = false): static
{
// TODO: Implement withUri() method.
$newInstance = clone $this;
$newInstance->uri = $uri;
return $newInstance;
}
}
+162
View File
@@ -0,0 +1,162 @@
<?php
namespace HttpMessage;
use Psr\Http\Message\UriInterface;
/**
*
*/
class Uri implements UriInterface
{
/**
* @var string
*/
public string $path = '';
/**
* @var string
*/
public string $host = '';
/**
* @var int
*/
public int $port = 0;
/**
* @var string
*/
public string $query = '';
/**
* @var string
*/
public string $scheme = '';
/**
* @return string
*/
public function getScheme(): string
{
// TODO: Implement getScheme() method.
return $this->scheme;
}
/**
* @return string
*/
public function getAuthority(): string
{
// TODO: Implement getAuthority() method.
return '';
}
public function getUserInfo()
{
// TODO: Implement getUserInfo() method.
}
/**
* @return string
*/
public function getHost(): string
{
// TODO: Implement getHost() method.
return $this->host;
}
/**
* @return int
*/
public function getPort(): int
{
// TODO: Implement getPort() method.
return $this->port;
}
/**
* @return string
*/
public function getPath(): string
{
// TODO: Implement getPath() method.
return $this->path;
}
/**
* @return string
*/
public function getQuery(): string
{
// TODO: Implement getQuery() method.
return $this->query;
}
/**
* @return string
*/
public function getFragment(): string
{
// TODO: Implement getFragment() method.
return $this->path;
}
/**
* @param string $scheme
* @return Uri|void
*/
public function withScheme($scheme): string
{
// TODO: Implement withScheme() method.
}
public function withUserInfo($user, $password = null)
{
// TODO: Implement withUserInfo() method.
}
public function withHost($host)
{
// TODO: Implement withHost() method.
}
public function withPort($port)
{
// TODO: Implement withPort() method.
}
public function withPath($path)
{
// TODO: Implement withPath() method.
}
public function withQuery($query)
{
// TODO: Implement withQuery() method.
}
public function withFragment($fragment)
{
// TODO: Implement withFragment() method.
}
public function __toString()
{
// TODO: Implement __toString() method.
}
}
+21 -1
View File
@@ -39,7 +39,7 @@ class ServerManager
public int $mode = SWOOLE_TCP;
private mixed $server = null;
private Server|null $server = null;
/**
@@ -161,6 +161,15 @@ class ServerManager
}
/**
* @return array
*/
public function getSetting(): array
{
return $this->server->setting;
}
/**
* @param array $ports
* @return array
@@ -431,6 +440,17 @@ class ServerManager
}
/**
* @param mixed $message
* @param int $workerId
* @return mixed
*/
public function sendMessage(mixed $message, int $workerId): mixed
{
return $this->server?->sendMessage($message, $workerId);
}
/**
* @param array $events
* @throws ReflectionException
+131 -20
View File
@@ -1,22 +1,133 @@
<?php
$A_DEFAULT = [
'Source' => '',
'Package' => '',
'Path' => '',
'Content-Type' => '',
'Method' => ''
];
$A_DEFAULT_1 = [
'REQUEST tcp/other.protocol v1.0',
'Source' => '127.0.0.1, 134.43.54.64',
'Package' => 'qat',
'Path' => 'getUserDetail',
'Content-Type' => 'application/json',
'Method' => 'rpcRequest',
'Meth21131od' => 'rpcRequest',
'Met231hod' => 'rpcRequest',
'Meth1231od' => 'rpcRequest',
'Meth12312od' => 'rpcRequest',
];
var_dump(array_diff_key($A_DEFAULT, $A_DEFAULT_1));
date_default_timezone_set('Asia/Shanghai');
class Crontab
{
public bool $isLoop = false;
const LOOP_TYPE_YEAR = 0;
const LOOP_TYPE_MONTH = 1;
const LOOP_TYPE_DAY = 2;
const LOOP_TYPE_HOUR = 3;
const LOOP_TYPE_MINUTE = 4;
const LOOP_TYPE_SECOND = 5;
public string $crontab = '2021 * * * */2 */5';
public int $loopType = Crontab::LOOP_TYPE_MINUTE;
private int $startTime = 0;
public int $loopTime = 2;
private int|string $year = 2021;
private int|string $month = 8;
private int|string $day = 25;
private int|string $hour = 19;
private int|string $minute = 02;
private int|string $second = 32;
public function __construct()
{
$this->startTime = time();
}
/**
* @return bool
*/
public function canExecute(): bool
{
$match = $this->next();
if (str_contains($match, '^')) {
return false;
}
return true;
}
public function next(): string
{
if ($this->loopType == Crontab::LOOP_TYPE_YEAR) $this->year = '*/' . $this->loopTime;
if ($this->loopType == Crontab::LOOP_TYPE_MONTH) $this->month = '*/' . $this->loopTime;
if ($this->loopType == Crontab::LOOP_TYPE_DAY) $this->day = '*/' . $this->loopTime;
if ($this->loopType == Crontab::LOOP_TYPE_HOUR) $this->hour = '*/' . $this->loopTime;
if ($this->loopType == Crontab::LOOP_TYPE_MINUTE) $this->minute = '*/' . $this->loopTime;
if ($this->loopType == Crontab::LOOP_TYPE_SECOND) $this->second = '*/' . $this->loopTime;
return sprintf('%s-%s-%s %s:%s:%s',
$this->format($this->year, 'Y'),
$this->format($this->month, 'm'),
$this->format($this->day, 'd'),
$this->format($this->hour, 'H'),
$this->format($this->minute, 'i'),
$this->format($this->second, 's')
);
}
/**
* @param string $text
* @param string $match
* @return string
*/
private function format(string $text, string $match): string
{
$time = date($match);
if ($text == '*') {
return $time;
}
if (str_contains($text, ',')) {
$explode = explode(',', $text);
sort($explode, SORT_NUMERIC);
if (in_array($time, $explode)) {
return $explode[array_search($time, $explode) + 1];
}
return '^';
}
if (str_contains($text, '-')) {
$explode = explode('-', $text);
if ($time >= $explode[0] && $time <= $explode[1]) {
return intval($time) + 1;
}
return '^';
}
if (str_contains($text, '/')) {
$explode = explode('/', $text);
if ($time % $this->loopTime !== 0) {
return '^';
}
if ($explode[0] != '*') {
return $explode[0] == $text ? $time : '^';
}
return $time;
}
return $time == $text ? $time : '^';
}
}
$c = new Crontab();
while (true) {
var_dump($c->next());
sleep(1);
}
+1 -169
View File
@@ -1,171 +1,3 @@
<?php
$str = '{"datacenter":"tencent-datacenter","data_dir":"/root/consul/data","log_file":"/root/consul/log/","log_level":"INFO","bind_addr":"0.0.0.0","client_addr":"0.0.0.0","node_name":"tencent-node","ui":true,"bootstrap_expect":1,"server":true,"acl":{"enabled":true,"default_policy":"deny","enable_token_persistence":true,"enable_key_list_policy":true}}';
//ini_set('memory_limit','3096M');
//
//use Snowflake\Application;
//
//require_once __DIR__ . '/vendor/autoload.php';
//$config = array_merge(
// require_once __DIR__ . '/System/Process/config.php',
// require_once __DIR__ . '/Http/config.php'
//);
//
//$application = new Application($config);
//$application->start();
//
//$replace = str_replace(__DIR__, '', __FILE__);
//var_dump(ltrim($replace, '/'));
//
//$comment = '@Handshake()';
//
//var_dump(preg_match('/@(Handshake)\((.*?)\)/', $comment, $events));
//var_dump($events);
//require_once __DIR__ . '/function.php';
//require_once __DIR__ . '/Http/Client/Result.php';
//require_once __DIR__ . '/Http/Client/HttpParse.php';
//require_once __DIR__ . '/Http/Client/Curl.php';
//
//\Swoole\Coroutine::create(function () {
// $curl = \Http\Client\Curl::NewRequest();
//// $curl->setCallback(function ($body) {
//// return $body;
//// });
//// var_dump($curl->get('https://www.baidu.com'));
//// $curl->setHost('www.baidu.com');
//// $curl->setIsSsl(true);
//// $curl->setCallback(function ($body) {
//// return $body;
//// });
//
//// var_dump($curl->get('https://test-api.zhuangb123.com/'));
//// var_dump($curl->post('https://test-api.zhuangb123.com/test'));
//// var_dump($curl->get('https://test-api.zhuangb123.com/2'));
//// var_dump($curl->get('https://test-api.zhuangb123.com/test'));
//// var_dump($curl->get('https://test-api.zhuangb123.com/'));
//// var_dump($curl->get('https://test-api.zhuangb123.com/test'));
////
//// $curl->clean('/test', [$curl::GET, $curl::POST]);
//// $curl->clean('/', [$curl::GET]);
////
////
// $curl->setHost('47.92.194.207');
// $curl->setPort(6602);
// var_dump($curl->get('/'));
//// var_dump($curl->post('/test'));
//// var_dump($curl->get('/'));
//// var_dump($curl->get('/test'));
//// var_dump($curl->get('/'));
//// var_dump($curl->get('/test'));
//// var_dump();
//});
//
//
////
//
////(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
////preg_match('/((http[s]?):\/\/)?(([\w-_]+\.)+\w+(:\d+)?)/', 'asdas.asd:4554/asdhagsdahsjs/asdassd/asdasd/as/d?id=akjsda&sdjkd=asdjasd', $out);
////var_dump($out);
//
//
////[$uri, $host, $isHttps, $domain, $_1, $_2, $path] = $out;
//// $out[0],$out[1],$out[3],$out[4],$out[7]
//
//$process = new \Swoole\Process(function (\Swoole\Process $process) {
// try {
// Swoole\Process::signal(9 | 15, function ($signo) {
// var_dump($signo);
// echo "shutdown.";
// file_put_contents(__DIR__ . '/log', __DIR__);
// });
// Swoole\Event::wait();
// }catch (Throwable $exception){
// var_dump($exception);
// }
// var_dump($process->pid);
//
//
// while (true) {
// Swoole\Coroutine::sleep(1);
// }
//
//}, false, 1, true);
//$process->start();
//
//$client = function ($name, callable $createCallback, callable $check, callable $release) {
// static $null = null;
// if (empty($null)) {
// $null = call_user_func($createCallback);
// }
// if (!call_user_func($check, $null)) {
// throw new Exception('check error.');
// }
// return $null;
//};
//
//
//$client(
// 'MyBuy',
// function () {
// return new stdClass();
// },
// function ($class) {
// return $class ? true : false;
// },
// function ($class) {
// unset($class);
// }
//);
////
////
//
//
//error_reporting(E_ALL);
//
//$a['hello'] = base64_encode(random_bytes(1000));
//$a['world'] = 'hello';
//$a['int'] = rand(1, 999999);
//$a['list'] = ['a,', 'b', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'];
//
//$val = serialize($a);
//$str = pack('N', strlen($val)) . $val . "\r\n";
//
//var_dump(swoole_substr_unserialize($val, strlen($val)));
//
//var_dump($str, unpack('N', pack('N', strlen($val))));
//var_dump( openssl_get_cipher_methods());
foreach (openssl_get_cipher_methods() as $openssl_get_cipher_method) {
$iv = '';
if (openssl_cipher_iv_length($openssl_get_cipher_method) > 0) {
continue;
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($openssl_get_cipher_method));
}
$tag = '';
$result = openssl_encrypt(json_encode([
'time' => microtime(),
'scene' => 'application',
'ot' => 1
]), $openssl_get_cipher_method, "xl.zhuangb123.com", 0, $iv, $tag);
echo $openssl_get_cipher_method . ',';
// if ($result != false) {
// echo str_pad($openssl_get_cipher_method, 30, ' ', STR_PAD_RIGHT) . '=> ' . str_replace('=', '', $result) . PHP_EOL;
// echo str_pad($openssl_get_cipher_method, 30, ' ', STR_PAD_RIGHT) . '=> ' . openssl_decrypt(str_replace('=', '', $result),
// $openssl_get_cipher_method, "xl.zhuangb123.com", 0, $iv, $tag) . PHP_EOL;
// }
}
var_dump(6%2);