Merge branch 'master' of https://gitee.com/dreamwithouttrace/snowflake into v1.0
This commit is contained in:
+9
-104
@@ -235,10 +235,7 @@ class Loader extends BaseObject
|
||||
$path = '/' . trim($path, '/');
|
||||
foreach ($this->_directory as $key => $_path) {
|
||||
$key = '/' . trim($key, '/');
|
||||
if (!str_starts_with($key, $path)) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($key, $outPath)) {
|
||||
if (!str_starts_with($key, $path) || in_array($key, $outPath)) {
|
||||
continue;
|
||||
}
|
||||
$this->execute($_path);
|
||||
@@ -279,98 +276,6 @@ class Loader extends BaseObject
|
||||
$array = '/' . trim(implode('/', $array), '/');
|
||||
|
||||
$this->_directory[$array][] = $className;
|
||||
|
||||
// $directory = $this->splitDirectory($filePath);
|
||||
// array_pop($directory);
|
||||
//
|
||||
// $tree = null;
|
||||
// foreach ($directory as $value) {
|
||||
// $tree = $this->getTree($tree, $value);
|
||||
// }
|
||||
//
|
||||
// if ($tree instanceof FileTree) {
|
||||
// $tree->addFile($className, $filePath);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $filePath
|
||||
* @param string|null $outPath
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
private function each(string $filePath, ?string $outPath): static
|
||||
{
|
||||
$tree = null;
|
||||
$directory = $this->splitDirectory($filePath);
|
||||
|
||||
$_tmp = '';
|
||||
if (!empty($outPath)) {
|
||||
$outPath = rtrim($outPath, '/');
|
||||
}
|
||||
|
||||
foreach ($directory as $key => $value) {
|
||||
$_tmp .= DIRECTORY_SEPARATOR . $value;
|
||||
if (!empty($outPath) && str_contains($_tmp, $outPath)) {
|
||||
break;
|
||||
}
|
||||
$tree = $this->getTree($tree, $value);
|
||||
}
|
||||
if ($tree instanceof FileTree) {
|
||||
$this->eachNode($tree->getChildes(), $outPath);
|
||||
$this->execute($tree->getFiles());
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $filePath
|
||||
* @return false|string[]
|
||||
*/
|
||||
private function splitDirectory(string $filePath): array|bool
|
||||
{
|
||||
$DIRECTORY = explode(DIRECTORY_SEPARATOR, $filePath);
|
||||
return array_filter($DIRECTORY, function ($value) {
|
||||
return !empty($value);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $tree
|
||||
* @param $value
|
||||
* @return FileTree
|
||||
*/
|
||||
private function getTree($tree, $value): FileTree
|
||||
{
|
||||
if ($tree === null) {
|
||||
$tree = $this->files->getChild($value);
|
||||
} else {
|
||||
$tree = $tree->getChild($value);
|
||||
}
|
||||
return $tree;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param FileTree[] $nodes
|
||||
* @param string|null $outPath
|
||||
* @throws Exception
|
||||
*/
|
||||
private function eachNode(array $nodes, ?string $outPath = '')
|
||||
{
|
||||
foreach ($nodes as $node) {
|
||||
$this->execute($node->getFiles());
|
||||
if (!empty($outPath) && str_contains($node->getDirPath(), $outPath)) {
|
||||
continue;
|
||||
}
|
||||
$childes = $node->getChildes();
|
||||
if (!empty($childes)) {
|
||||
$this->eachNode($childes, $outPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -395,31 +300,31 @@ class Loader extends BaseObject
|
||||
if (empty($classes)) {
|
||||
return;
|
||||
}
|
||||
$annotation = Snowflake::app()->getAnnotation();
|
||||
$annotation = Snowflake::getAnnotation();
|
||||
foreach ($classes as $className) {
|
||||
$annotations = $this->_classes[$className] ?? null;
|
||||
if ($annotations === null) {
|
||||
continue;
|
||||
}
|
||||
$class = clone $annotations['handler'];
|
||||
foreach ($annotations['target'] ?? [] as $value) {
|
||||
$value->execute([$annotations['handler']]);
|
||||
$value->execute([$class]);
|
||||
}
|
||||
|
||||
$_className = $annotations['handler']::class;
|
||||
foreach ($annotations['methods'] as $name => $attribute) {
|
||||
foreach ($attribute as $value) {
|
||||
if ($value instanceof Relation) {
|
||||
$annotation->addRelate($_className, $value->name, $name);
|
||||
$annotation->addRelate($class::class, $value->name, $name);
|
||||
} else if ($value instanceof Get) {
|
||||
$annotation->addGets($_className, $value->name, $name);
|
||||
$annotation->addGets($class::class, $value->name, $name);
|
||||
} else if ($value instanceof Set) {
|
||||
$annotation->addSets($_className, $value->name, $name);
|
||||
$annotation->addSets($class::class, $value->name, $name);
|
||||
} else {
|
||||
$value->execute([$annotations['handler'], $name]);
|
||||
$value->execute([$class, $name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -342,12 +342,10 @@ class ActiveRecord extends BaseActiveRecord
|
||||
*/
|
||||
public function hasOne(string $modelName, $foreignKey, $localKey): HasOne|ActiveQuery
|
||||
{
|
||||
if (!$this->has($localKey)) {
|
||||
if (($value = $this->getAttribute($localKey)) === null) {
|
||||
throw new Exception("Need join table primary key.");
|
||||
}
|
||||
|
||||
$value = $this->getAttribute($localKey);
|
||||
|
||||
$relation = $this->getRelation();
|
||||
|
||||
return new HasOne($modelName, $foreignKey, $value, $relation);
|
||||
@@ -363,12 +361,10 @@ class ActiveRecord extends BaseActiveRecord
|
||||
*/
|
||||
public function hasCount($modelName, $foreignKey, $localKey): mixed
|
||||
{
|
||||
if (!$this->has($localKey)) {
|
||||
if (($value = $this->getAttribute($localKey)) === null) {
|
||||
throw new Exception("Need join table primary key.");
|
||||
}
|
||||
|
||||
$value = $this->getAttribute($localKey);
|
||||
|
||||
$relation = $this->getRelation();
|
||||
|
||||
return new HasCount($modelName, $foreignKey, $value, $relation);
|
||||
@@ -384,12 +380,10 @@ class ActiveRecord extends BaseActiveRecord
|
||||
*/
|
||||
public function hasMany($modelName, $foreignKey, $localKey): mixed
|
||||
{
|
||||
if (!$this->has($localKey)) {
|
||||
if (($value = $this->getAttribute($localKey)) === null) {
|
||||
throw new Exception("Need join table primary key.");
|
||||
}
|
||||
|
||||
$value = $this->getAttribute($localKey);
|
||||
|
||||
$relation = $this->getRelation();
|
||||
|
||||
return new HasMany($modelName, $foreignKey, $value, $relation);
|
||||
@@ -404,12 +398,10 @@ class ActiveRecord extends BaseActiveRecord
|
||||
*/
|
||||
public function hasIn($modelName, $foreignKey, $localKey): mixed
|
||||
{
|
||||
if (!$this->has($localKey)) {
|
||||
if (($value = $this->getAttribute($localKey)) === null) {
|
||||
throw new Exception("Need join table primary key.");
|
||||
}
|
||||
|
||||
$value = $this->getAttribute($localKey);
|
||||
|
||||
$relation = $this->getRelation();
|
||||
|
||||
return new HasMany($modelName, $foreignKey, $value, $relation);
|
||||
|
||||
@@ -968,7 +968,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
|
||||
*/
|
||||
public function offsetExists(mixed $offset): bool
|
||||
{
|
||||
return $this->has($offset);
|
||||
return isset($this->_attributes[$offset]) || isset($this->_oldAttributes[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -997,7 +997,8 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess
|
||||
*/
|
||||
public function offsetUnset(mixed $offset)
|
||||
{
|
||||
if (!$this->has($offset)) {
|
||||
if (!isset($this->_attributes[$offset])
|
||||
&& !isset($this->_oldAttributes[$offset])) {
|
||||
return;
|
||||
}
|
||||
unset($this->_attributes[$offset]);
|
||||
|
||||
@@ -121,15 +121,11 @@ class Command extends Component
|
||||
private function execute($type, $isInsert = null, $hasAutoIncrement = null): int|bool|array|string|null
|
||||
{
|
||||
try {
|
||||
$time = microtime(true);
|
||||
if ($type === static::EXECUTE) {
|
||||
$result = $this->insert_or_change($isInsert, $hasAutoIncrement);
|
||||
} else {
|
||||
$result = $this->search($type);
|
||||
}
|
||||
if (microtime(true) - $time >= 0.03) {
|
||||
$this->warning('execute sql Worker.' . env('worker') . '.' . Coroutine::getCid() . '`' . $this->sql . '` use time ' . (microtime(true) - $time));
|
||||
}
|
||||
return $result;
|
||||
} catch (\Throwable $exception) {
|
||||
return $this->addError($this->sql . '. error: ' . $exception->getMessage(), 'mysql');
|
||||
@@ -144,11 +140,7 @@ class Command extends Component
|
||||
*/
|
||||
private function search($type): mixed
|
||||
{
|
||||
$time = microtime(true);
|
||||
$connect = $this->db->getConnect($this->sql);
|
||||
if (microtime(true) - $time > 0.02) {
|
||||
$this->error('get connect time:' . $this->sql . '; ' . (microtime(true) - $time));
|
||||
}
|
||||
if (!($query = $connect?->query($this->sql))) {
|
||||
return $this->addError($connect->errorInfo()[2] ?? '数据库异常, 请稍后再试.');
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use HttpServer\Abstracts\Callback;
|
||||
use Snowflake\Event;
|
||||
use Snowflake\Exception\ConfigException;
|
||||
use Snowflake\Snowflake;
|
||||
use Swoole\Coroutine;
|
||||
use Swoole\Coroutine\System;
|
||||
use Swoole\Server;
|
||||
|
||||
@@ -32,10 +33,7 @@ class OnWorkerStart extends Callback
|
||||
putenv('state=start');
|
||||
putenv('worker=' . $worker_id);
|
||||
|
||||
$content = System::readFile(storage('runtime.php'));
|
||||
|
||||
$annotation = Snowflake::app()->getAnnotation();
|
||||
$annotation->setLoader(unserialize($content));
|
||||
$annotation = $this->settings();
|
||||
if ($worker_id < $server->setting['worker_num']) {
|
||||
$this->onWorker($server, $annotation);
|
||||
} else {
|
||||
@@ -44,6 +42,21 @@ class OnWorkerStart extends Callback
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return \Annotation\Annotation
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function settings(): Annotation
|
||||
{
|
||||
$content = System::readFile(storage('runtime.php'));
|
||||
|
||||
$annotation = Snowflake::app()->getAnnotation();
|
||||
$annotation->setLoader(unserialize($content));
|
||||
|
||||
return $annotation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $worker_id
|
||||
|
||||
+14
-20
@@ -16,7 +16,6 @@ class Context extends BaseContext
|
||||
protected static array $_contents = [];
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param $context
|
||||
@@ -25,11 +24,10 @@ class Context extends BaseContext
|
||||
*/
|
||||
public static function setContext($id, $context, $key = null): mixed
|
||||
{
|
||||
if (static::inCoroutine()) {
|
||||
return self::setCoroutine($id, $context, $key);
|
||||
} else {
|
||||
return self::setStatic($id, $context, $key);
|
||||
if (!static::inCoroutine()) {
|
||||
return static::setStatic($id, $context, $key);
|
||||
}
|
||||
return self::setCoroutine($id, $context, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,9 +76,6 @@ class Context extends BaseContext
|
||||
*/
|
||||
public static function increment($id, $key = null, $value = 1): bool|int
|
||||
{
|
||||
if (!static::inCoroutine()) {
|
||||
return false;
|
||||
}
|
||||
if (!isset(Coroutine::getContext()[$id][$key])) {
|
||||
return false;
|
||||
}
|
||||
@@ -95,7 +90,7 @@ class Context extends BaseContext
|
||||
*/
|
||||
public static function decrement($id, $key = null, $value = 1): bool|int
|
||||
{
|
||||
if (!static::inCoroutine() || !static::hasContext($id)) {
|
||||
if (!static::hasContext($id)) {
|
||||
return false;
|
||||
}
|
||||
if (!isset(Coroutine::getContext()[$id][$key])) {
|
||||
@@ -111,14 +106,10 @@ class Context extends BaseContext
|
||||
*/
|
||||
public static function getContext($id, $key = null): mixed
|
||||
{
|
||||
if (!static::hasContext($id)) {
|
||||
return null;
|
||||
}
|
||||
if (static::inCoroutine()) {
|
||||
return static::loadByContext($id, $key);
|
||||
} else {
|
||||
if (!static::inCoroutine()) {
|
||||
return static::loadByStatic($id, $key);
|
||||
}
|
||||
return static::loadByContext($id, $key);
|
||||
}
|
||||
|
||||
|
||||
@@ -179,16 +170,20 @@ class Context extends BaseContext
|
||||
if (!static::hasContext($id, $key)) {
|
||||
return;
|
||||
}
|
||||
if (static::inCoroutine()) {
|
||||
if (!static::inCoroutine()) {
|
||||
if (!empty($key)) {
|
||||
unset(static::$_contents[$id][$key]);
|
||||
} else {
|
||||
unset(static::$_contents[$id]);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!empty($key)) {
|
||||
unset(Coroutine::getContext()[$id][$key]);
|
||||
} else {
|
||||
unset(Coroutine::getContext()[$id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
@@ -199,9 +194,8 @@ class Context extends BaseContext
|
||||
{
|
||||
if (!static::inCoroutine()) {
|
||||
return static::searchByStatic($id, $key);
|
||||
} else {
|
||||
return static::searchByCoroutine($id, $key);
|
||||
}
|
||||
return static::searchByCoroutine($id, $key);
|
||||
}
|
||||
|
||||
|
||||
@@ -244,7 +238,7 @@ class Context extends BaseContext
|
||||
*/
|
||||
public static function inCoroutine(): bool
|
||||
{
|
||||
return Coroutine::getCid() > 0;
|
||||
return Coroutine::getCid() !== -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -115,7 +115,11 @@ class Server extends HttpService
|
||||
|
||||
Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL ^ SWOOLE_HOOK_BLOCKING_FUNCTION);
|
||||
|
||||
Coroutine::set(['enable_deadlock_check' => false]);
|
||||
$settings['enable_deadlock_check'] = false;
|
||||
$settings['exit_condition'] = function () {
|
||||
return Coroutine::stats()['coroutine_num'] === 0;
|
||||
};
|
||||
Coroutine::set($settings);
|
||||
|
||||
return $this->execute($baseServer);
|
||||
}
|
||||
|
||||
@@ -174,11 +174,7 @@ abstract class Pool extends Component
|
||||
if ($this->_items[$name]->isEmpty()) {
|
||||
$this->createByCallback($name, $callback);
|
||||
}
|
||||
$time = microtime(true);
|
||||
$connection = $this->_items[$name]->pop(0.002);
|
||||
if (($end = microtime(true) - $time) >= 0.01) {
|
||||
$this->error('waite channel connect use time.' . $end);
|
||||
}
|
||||
if (!$this->checkCanUse($name, $connection)) {
|
||||
return $this->createClient($name, $callback);
|
||||
} else {
|
||||
|
||||
+8
-13
@@ -29,6 +29,9 @@ class Channel extends Component
|
||||
public function push(mixed $value, string $name = ''): void
|
||||
{
|
||||
$channel = $this->channelInit($name);
|
||||
if ($channel->count() >= 100) {
|
||||
return;
|
||||
}
|
||||
$channel->enqueue($value);
|
||||
}
|
||||
|
||||
@@ -71,21 +74,13 @@ class Channel extends Component
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function pop(string $name, Closure $closure, int|float $timeout = null): mixed
|
||||
public function pop(string $name, Closure $closure): mixed
|
||||
{
|
||||
if (($channel = $this->channelInit($name)) == false) {
|
||||
return $this->addError('Channel is full.');
|
||||
$channel = $this->channelInit($name);
|
||||
if ($channel->isEmpty()) {
|
||||
return call_user_func($closure);
|
||||
}
|
||||
if (!$channel->isEmpty()) {
|
||||
return $channel->shift();
|
||||
}
|
||||
if ($timeout !== null) {
|
||||
$data = $channel->dequeue();
|
||||
}
|
||||
if (empty($data)) {
|
||||
$data = call_user_func($closure);
|
||||
}
|
||||
return $data;
|
||||
return $channel->dequeue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -467,6 +467,9 @@ mlAZUEjsoaT9vjvjGTxl3uCm0TX5KTgtSJIt2kA1tYVjQef+/iZTHxY=
|
||||
if (!empty($source)) {
|
||||
$this->data['source'] = $source;
|
||||
}
|
||||
if (!isset($this->data['token'])) {
|
||||
return;
|
||||
}
|
||||
$key = $this->authKey($this->getSource(), $this->data['token']);
|
||||
$this->getRedis()->expire($key, $this->timeout);
|
||||
}
|
||||
|
||||
@@ -154,6 +154,7 @@ class Connection extends Pool
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
PDO::ATTR_CASE => PDO::CASE_NATURAL,
|
||||
PDO::ATTR_TIMEOUT => $this->timeout,
|
||||
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
|
||||
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . ($config['charset'] ?? 'utf8mb4')
|
||||
]);
|
||||
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
Reference in New Issue
Block a user