mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 07:54:19 +00:00
Extract MainLoggerThread unit from MainLogger
MainLogger is no longer a Thread, as per the recent changes to pocketmine/log-pthreads.
This commit is contained in:
parent
4b9639f6c9
commit
ae75d73f48
12
composer.lock
generated
12
composer.lock
generated
@ -513,17 +513,17 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/LogPthreads.git",
|
||||
"reference": "273e4ba9715c7eb916c6e50e0b92ac43b7ac389e"
|
||||
"reference": "634af620e1cb3b4f3c7ed356cc31d778b00fd717"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/273e4ba9715c7eb916c6e50e0b92ac43b7ac389e",
|
||||
"reference": "273e4ba9715c7eb916c6e50e0b92ac43b7ac389e",
|
||||
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/634af620e1cb3b4f3c7ed356cc31d778b00fd717",
|
||||
"reference": "634af620e1cb3b4f3c7ed356cc31d778b00fd717",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "~3.2.0",
|
||||
"php": ">=7.2",
|
||||
"php": "^7.2 || ^8.0",
|
||||
"pocketmine/log": "^0.2.0 || dev-master"
|
||||
},
|
||||
"conflict": {
|
||||
@ -531,7 +531,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "0.12.63",
|
||||
"phpstan/phpstan": "0.12.71",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.4"
|
||||
},
|
||||
"type": "library",
|
||||
@ -549,7 +549,7 @@
|
||||
"issues": "https://github.com/pmmp/LogPthreads/issues",
|
||||
"source": "https://github.com/pmmp/LogPthreads/tree/master"
|
||||
},
|
||||
"time": "2021-01-06T21:23:23+00:00"
|
||||
"time": "2021-02-04T15:41:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/math",
|
||||
|
@ -18,6 +18,7 @@ includes:
|
||||
|
||||
rules:
|
||||
- pocketmine\phpstan\rules\DisallowEnumComparisonRule
|
||||
# - pocketmine\phpstan\rules\ThreadedSupportedTypesRule
|
||||
|
||||
parameters:
|
||||
level: 8
|
||||
|
@ -272,8 +272,7 @@ namespace pocketmine {
|
||||
}
|
||||
}while(false);
|
||||
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
$logger->shutdownLogWriterThread();
|
||||
|
||||
echo Terminal::$FORMAT_RESET . PHP_EOL;
|
||||
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use function min;
|
||||
|
||||
final class EntitySizeInfo{
|
||||
/** @var float */
|
||||
private $height;
|
||||
|
@ -30,6 +30,7 @@ use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\data\bedrock\DyeColorIdMap;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use function count;
|
||||
|
||||
class Banner extends ItemBlockWallOrFloor{
|
||||
public const TAG_PATTERNS = TileBanner::TAG_PATTERNS;
|
||||
|
@ -30,9 +30,9 @@ use pocketmine\network\mcpe\protocol\serializer\PacketSerializer;
|
||||
use pocketmine\network\mcpe\protocol\types\DimensionIds;
|
||||
use pocketmine\network\mcpe\protocol\types\MapDecoration;
|
||||
use pocketmine\network\mcpe\protocol\types\MapTrackedObject;
|
||||
use function count;
|
||||
#ifndef COMPILE
|
||||
use pocketmine\utils\Binary;
|
||||
#ifndef COMPILE
|
||||
use function count;
|
||||
#endif
|
||||
|
||||
class ClientboundMapItemDataPacket extends DataPacket implements ClientboundPacket{
|
||||
|
@ -23,7 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
use function getmypid;
|
||||
use function preg_match;
|
||||
|
||||
trait EnumTrait{
|
||||
|
@ -27,11 +27,7 @@ use LogLevel;
|
||||
use pocketmine\errorhandler\ErrorTypeToStringMap;
|
||||
use pocketmine\thread\Thread;
|
||||
use pocketmine\thread\Worker;
|
||||
use function fclose;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function get_class;
|
||||
use function is_resource;
|
||||
use function preg_replace;
|
||||
use function sprintf;
|
||||
use function touch;
|
||||
@ -43,14 +39,8 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
|
||||
/** @var string */
|
||||
protected $logFile;
|
||||
/** @var \Threaded */
|
||||
protected $logStream;
|
||||
/** @var bool */
|
||||
protected $shutdown = false;
|
||||
/** @var bool */
|
||||
protected $logDebug;
|
||||
/** @var bool */
|
||||
private $syncFlush = false;
|
||||
|
||||
/** @var string */
|
||||
private $format = TextFormat::AQUA . "[%s] " . TextFormat::RESET . "%s[%s/%s]: %s" . TextFormat::RESET;
|
||||
@ -61,6 +51,9 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
/** @var string */
|
||||
private $timezone;
|
||||
|
||||
/** @var MainLoggerThread */
|
||||
private $logWriterThread;
|
||||
|
||||
/**
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
@ -69,13 +62,13 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
touch($logFile);
|
||||
$this->logFile = $logFile;
|
||||
$this->logDebug = $logDebug;
|
||||
$this->logStream = new \Threaded;
|
||||
|
||||
//Child threads may not inherit command line arguments, so if there's an override it needs to be recorded here
|
||||
$this->mainThreadHasFormattingCodes = Terminal::hasFormattingCodes();
|
||||
$this->timezone = Timezone::get();
|
||||
|
||||
$this->start(PTHREADS_INHERIT_NONE);
|
||||
$this->logWriterThread = new MainLoggerThread($this->logFile);
|
||||
$this->logWriterThread->start(PTHREADS_INHERIT_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,9 +211,12 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
$this->synchronized($c);
|
||||
}
|
||||
|
||||
public function shutdown() : void{
|
||||
$this->shutdown = true;
|
||||
$this->notify();
|
||||
public function shutdownLogWriterThread() : void{
|
||||
if(\Thread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){
|
||||
$this->logWriterThread->shutdown();
|
||||
}else{
|
||||
throw new \LogicException("Only the creator thread can shutdown the logger thread");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,54 +250,17 @@ class MainLogger extends \AttachableThreadedLogger implements \BufferedLogger{
|
||||
$attachment->call($level, $message);
|
||||
}
|
||||
|
||||
$this->logStream[] = $time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL;
|
||||
$this->notify();
|
||||
$this->logWriterThread->write($time->format("Y-m-d") . " " . TextFormat::clean($message) . PHP_EOL);
|
||||
});
|
||||
}
|
||||
|
||||
public function syncFlushBuffer() : void{
|
||||
$this->syncFlush = true;
|
||||
$this->synchronized(function() : void{
|
||||
$this->notify(); //write immediately
|
||||
|
||||
while($this->syncFlush){
|
||||
$this->wait(); //block until it's all been written to disk
|
||||
}
|
||||
});
|
||||
$this->logWriterThread->syncFlushBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $logResource
|
||||
*/
|
||||
private function writeLogStream($logResource) : void{
|
||||
while($this->logStream->count() > 0){
|
||||
$chunk = $this->logStream->shift();
|
||||
fwrite($logResource, $chunk);
|
||||
public function __destruct(){
|
||||
if(!$this->logWriterThread->isJoined() && \Thread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){
|
||||
$this->shutdownLogWriterThread();
|
||||
}
|
||||
|
||||
$this->synchronized(function() : void{
|
||||
if($this->syncFlush){
|
||||
$this->syncFlush = false;
|
||||
$this->notify(); //if this was due to a sync flush, tell the caller to stop waiting
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function run() : void{
|
||||
$logResource = fopen($this->logFile, "ab");
|
||||
if(!is_resource($logResource)){
|
||||
throw new \RuntimeException("Couldn't open log file");
|
||||
}
|
||||
|
||||
while(!$this->shutdown){
|
||||
$this->writeLogStream($logResource);
|
||||
$this->synchronized(function() : void{
|
||||
$this->wait();
|
||||
});
|
||||
}
|
||||
|
||||
$this->writeLogStream($logResource);
|
||||
|
||||
fclose($logResource);
|
||||
}
|
||||
}
|
||||
|
101
src/utils/MainLoggerThread.php
Normal file
101
src/utils/MainLoggerThread.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\utils;
|
||||
|
||||
use function fclose;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function is_resource;
|
||||
|
||||
final class MainLoggerThread extends \Thread{
|
||||
|
||||
private string $logFile;
|
||||
private \Threaded $buffer;
|
||||
private bool $syncFlush = false;
|
||||
private bool $shutdown = false;
|
||||
|
||||
public function __construct(string $logFile){
|
||||
$this->buffer = new \Threaded();
|
||||
$this->logFile = $logFile;
|
||||
}
|
||||
|
||||
public function write(string $line) : void{
|
||||
$this->synchronized(function() use ($line) : void{
|
||||
$this->buffer[] = $line;
|
||||
$this->notify();
|
||||
});
|
||||
}
|
||||
|
||||
public function syncFlushBuffer() : void{
|
||||
$this->syncFlush = true;
|
||||
$this->synchronized(function() : void{
|
||||
$this->notify(); //write immediately
|
||||
|
||||
while($this->syncFlush){
|
||||
$this->wait(); //block until it's all been written to disk
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function shutdown() : void{
|
||||
$this->shutdown = true;
|
||||
$this->notify();
|
||||
$this->join();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $logResource
|
||||
*/
|
||||
private function writeLogStream($logResource) : void{
|
||||
while($this->buffer->count() > 0){
|
||||
$chunk = $this->buffer->shift();
|
||||
fwrite($logResource, $chunk);
|
||||
}
|
||||
|
||||
$this->synchronized(function() : void{
|
||||
if($this->syncFlush){
|
||||
$this->syncFlush = false;
|
||||
$this->notify(); //if this was due to a sync flush, tell the caller to stop waiting
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function run() : void{
|
||||
$logResource = fopen($this->logFile, "ab");
|
||||
if(!is_resource($logResource)){
|
||||
throw new \RuntimeException("Couldn't open log file");
|
||||
}
|
||||
|
||||
while(!$this->shutdown){
|
||||
$this->writeLogStream($logResource);
|
||||
$this->synchronized(function() : void{
|
||||
$this->wait();
|
||||
});
|
||||
}
|
||||
|
||||
$this->writeLogStream($logResource);
|
||||
|
||||
fclose($logResource);
|
||||
}
|
||||
}
|
@ -21,13 +21,13 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
if(!defined('LEVELDB_ZLIB_RAW_COMPRESSION')){
|
||||
if(!\defined('LEVELDB_ZLIB_RAW_COMPRESSION')){
|
||||
//leveldb might not be loaded
|
||||
define('LEVELDB_ZLIB_RAW_COMPRESSION', 4);
|
||||
\define('LEVELDB_ZLIB_RAW_COMPRESSION', 4);
|
||||
}
|
||||
if(!extension_loaded('libdeflate')){
|
||||
if(!\extension_loaded('libdeflate')){
|
||||
function libdeflate_deflate_compress(string $data, int $level = 6) : string{}
|
||||
}
|
||||
|
||||
//TODO: these need to be defined properly or removed
|
||||
define('pocketmine\COMPOSER_AUTOLOADER_PATH', dirname(__DIR__, 2) . '/vendor/autoload.php');
|
||||
\define('pocketmine\COMPOSER_AUTOLOADER_PATH', \dirname(__DIR__, 2) . '/vendor/autoload.php');
|
||||
|
@ -283,7 +283,7 @@ parameters:
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$str of function fwrite expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: ../../../src/utils/MainLogger.php
|
||||
path: ../../../src/utils/MainLoggerThread.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access offset 'status' on mixed\\.$#"
|
||||
|
@ -21,14 +21,14 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require dirname(__DIR__, 3) . '/vendor/autoload.php';
|
||||
require \dirname(__DIR__, 3) . '/vendor/autoload.php';
|
||||
|
||||
/* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */
|
||||
|
||||
$factory = new \pocketmine\block\BlockFactory();
|
||||
|
||||
$old = json_decode(file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true);
|
||||
$new = array_map(
|
||||
$old = \json_decode(\file_get_contents(__DIR__ . '/block_factory_consistency_check.json'), true);
|
||||
$new = \array_map(
|
||||
function(\pocketmine\block\Block $block) : string{
|
||||
return $block->getName();
|
||||
},
|
||||
@ -46,6 +46,6 @@ foreach($new as $k => $name){
|
||||
echo "Name changed (" . ($k >> 4) . ":" . ($k & 0xf) . "): " . $old[$k] . " -> " . $name . "\n";
|
||||
}
|
||||
}
|
||||
file_put_contents(__DIR__ . '/block_factory_consistency_check.json', json_encode(
|
||||
\file_put_contents(__DIR__ . '/block_factory_consistency_check.json', \json_encode(
|
||||
$new
|
||||
));
|
||||
|
@ -50,8 +50,7 @@ class AsyncPoolTest extends TestCase{
|
||||
|
||||
public function tearDown() : void{
|
||||
$this->pool->shutdown();
|
||||
$this->mainLogger->shutdown();
|
||||
$this->mainLogger->join();
|
||||
$this->mainLogger->shutdownLogWriterThread();
|
||||
}
|
||||
|
||||
public function testTaskLeak() : void{
|
||||
|
Loading…
x
Reference in New Issue
Block a user