1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 05:58:58 +01:00

Better shutdown and signal logging

This commit is contained in:
Daniil Gentili 2019-06-08 21:01:57 +02:00
parent 11fa07b5d3
commit 73dc3fbcfd
8 changed files with 59 additions and 20 deletions

View File

@ -36,7 +36,6 @@ class API extends APIFactory
public function __magic_construct($params = [], $settings = [])
{
Magic::class_exists();
set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
$deferred = new Deferred();
$this->asyncAPIPromise = $deferred->promise();
$this->asyncAPIPromise->onResolve(function () {
@ -131,6 +130,7 @@ class API extends APIFactory
if (isset($unserialized->API)) {
$this->API = $unserialized->API;
$this->APIFactory();
$unserialized->donotlog = true;
$deferred->resolve();
yield $this->API->initAsync();
$this->APIFactory();
@ -187,14 +187,16 @@ class API extends APIFactory
if ($this->asyncInitPromise) {
$this->init();
}
if ($this->API) {
$this->API->logger('Shutting down MadelineProto (normally or due to an exception, idk)');
$this->API->destructing = true;
} else {
Logger::log('Shutting down MadelineProto (normally or due to an exception, idk)');
if (!isset($this->donotlog)) {
if ($this->API) {
$this->API->logger('Shutting down MadelineProto (normally or due to an exception, idk)');
$this->API->destructing = true;
} else {
Logger::log('Shutting down MadelineProto (normally or due to an exception, idk)');
}
$this->destructing = true;
$this->wait($this->serialize());
}
$this->destructing = true;
$this->wait($this->serialize());
//restore_error_handler();
}

View File

@ -86,4 +86,14 @@ class Exception extends \Exception
throw new self($errstr, $errno, null, $errfile, $errline);
}
/**
* ExceptionErrorHandler.
*
* Error handler
*/
public static function ExceptionHandler($exception)
{
Logger::log($exception, Logger::FATAL_ERROR);
}
}

View File

@ -166,8 +166,8 @@ class Logger
$param = Magic::$isatty ? "\33[".$this->colors[$level].'m'.$param."\33[0m".$this->newline : $param.$this->newline;
if ($this->stdout->write($param) instanceof Failure) {
switch ($this->mode) {
case 3: echo "(closed) $param"; break;
case 2: file_put_contents($this->optional, "(closed) $param", FILE_APPEND); break;
case 3: echo $param; break;
case 2: file_put_contents($this->optional, $param, FILE_APPEND); break;
}
}
break;

View File

@ -220,11 +220,11 @@ class FeedLoop extends ResumableSignalLoop
$this->API->logger->logger("Not enough data: for message update $log, getting difference...", \danog\MadelineProto\Logger::VERBOSE);
$update = ['_' => 'updateChannelTooLong'];
if ($channelId && !yield $this->API->peer_isset_async($this->API->to_supergroup($channelId))) $channelId = false;
if ($channelId && $to) $channelId = false;
}
break;
default:
if ($channelId !== false && !yield $this->API->peer_isset_async($this->API->to_supergroup($channelId))) {
if ($channelId && !yield $this->API->peer_isset_async($this->API->to_supergroup($channelId))) {
$this->API->logger->logger('Skipping update, I do not have the channel id '.$channelId, \danog\MadelineProto\Logger::ERROR);
return;
@ -232,7 +232,11 @@ class FeedLoop extends ResumableSignalLoop
break;
}
if ($channelId !== $this->channelId) {
return yield $this->API->feeders[$channelId]->feedSingle($update);
if (isset($this->API->feeders[$channelId])) {
return yield $this->API->feeders[$channelId]->feedSingle($update);
} else if ($this->channelId) {
return yield $this->API->feeders[false]->feedSingle($update);
}
}
$this->API->logger->logger('Was fed an update of type '.$update['_']." in $this...", \danog\MadelineProto\Logger::VERBOSE);

View File

@ -233,9 +233,11 @@ class MTProto extends AsyncConstruct implements TLCallback
return ['supportUser', 'referenceDatabase', 'channel_participants', 'event_handler', 'event_handler_instance', 'loop_callback', 'web_template', 'encrypted_layer', 'settings', 'config', 'authorization', 'authorized', 'rsa_keys', 'dh_config', 'chats', 'last_stored', 'qres', 'got_state', 'channels_state', 'updates', 'updates_key', 'full_chats', 'msg_ids', 'dialog_params', 'datacenter', 'v', 'constructors', 'td_constructors', 'methods', 'td_methods', 'td_descriptions', 'tl_callbacks', 'temp_requested_secret_chats', 'temp_rekeyed_secret_chats', 'secret_chats', 'hook_url', 'storage', 'authorized_dc', 'tos'];
}
public function logger(...$params)
public function logger($param, $level = Logger::NOTICE, $file = null)
{
return $this->logger->logger(...$params);
if ($file === null) $file = basename(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['file'], '.php');
return $this->logger->logger($param, $level, $file);
}
public function isAltervista()
{
@ -460,9 +462,26 @@ class MTProto extends AsyncConstruct implements TLCallback
if ($this->phoneConfigWatcherId) {
Loop::cancel($this->phoneConfigWatcherId);
}
if (\danog\MadelineProto\Magic::$has_thread && is_object(\Thread::getCurrentThread())) {
return;
$channelIds = [];
foreach ($this->channels_state->get() as $state) {
$channelIds []= $state->getChannel();
}
sort($channelIds);
foreach ($channelIds as $channelId) {
if (isset($this->feeders[$channelId])) {
$this->feeders[$channelId]->signal(true);
}
if (!isset($this->updaters[$channelId])) {
$this->updaters[$channelId]->signal(true);
}
}
if (isset($this->seqUpdater)) {
$this->seqUpdater->signal(true);
}
foreach ($this->datacenter->sockets as $datacenter) {
$datacenter->disconnect();
}
$this->logger("Successfully destroyed MadelineProto");
}
public function serialize()

View File

@ -58,6 +58,8 @@ class Magic
public static function class_exists()
{
set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
//set_exception_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionHandler']);
if (!self::$inited) {
self::$has_thread = class_exists('\\Thread') && method_exists('\\Thread', 'getCurrentThread');
self::$BIG_ENDIAN = pack('L', 1) === pack('N', 1);
@ -133,8 +135,9 @@ class Magic
}
// Even an empty handler is enough to catch ctrl+c
if (defined('SIGINT')) {
Loop::onSignal(SIGINT, static function () { die(); });
Loop::onSignal(SIGTERM, static function () { die(); });
if (function_exists('pcntl_async_signals')) pcntl_async_signals(true);
Loop::onSignal(SIGINT, static function () { Logger::log('Got sigint', Logger::FATAL_ERROR); die(); });
Loop::onSignal(SIGTERM, static function () { Logger::log('Got sigterm', Logger::FATAL_ERROR); die(); });
}
self::$inited = true;
}

View File

@ -39,7 +39,7 @@ trait SeqNoHandler
{
$type = isset($this->incoming_messages[$current_msg_id]['content']['_']) ? $this->incoming_messages[$current_msg_id]['content']['_'] : '-';
if (isset($this->incoming_messages[$current_msg_id]['seq_no']) && ($seq_no = $this->generate_in_seq_no($this->content_related($this->incoming_messages[$current_msg_id]['content']))) !== $this->incoming_messages[$current_msg_id]['seq_no']) {
$this->API->logger->logger('SECURITY WARNING: Seqno mismatch (should be '.$seq_no.', is '.$this->incoming_messages[$current_msg_id]['seq_no'].', '.$type.')', \danog\MadelineProto\Logger::ERROR);
$this->API->logger->logger('SECURITY WARNING: Seqno mismatch (should be '.$seq_no.', is '.$this->incoming_messages[$current_msg_id]['seq_no'].', '.$type.')', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
} elseif (isset($seq_no)) {
$this->API->logger->logger('Seqno OK (should be '.$seq_no.', is '.$this->incoming_messages[$current_msg_id]['seq_no'].', '.$type.')', \danog\MadelineProto\Logger::ULTRA_VERBOSE);
}

View File

@ -51,6 +51,7 @@ trait Loop
return false;
}
$this->logger->logger('Starting event loop');
if (!is_callable($this->loop_callback) || (is_array($this->loop_callback) && $this->loop_callback[1] === 'onLoop' && !method_exists(...$this->loop_callback))) {
$this->loop_callback = null;
}