diff --git a/src/danog/MadelineProto/API.php b/src/danog/MadelineProto/API.php index 85dfbc51..43dbd8b7 100644 --- a/src/danog/MadelineProto/API.php +++ b/src/danog/MadelineProto/API.php @@ -189,7 +189,7 @@ class API extends InternalDoc if ($settings instanceof SettingsIpc) { $forceFull = $forceFull || $settings->getForceFull(); } elseif ($settings instanceof Settings) { - $forceFull = $forceFull || $settings->getSerialization()->getForceFull(); + $forceFull = $forceFull || $settings->getIpc()->getForceFull(); } [$unserialized, $this->unlock] = yield Tools::timeoutWithDefault( @@ -250,13 +250,15 @@ class API extends InternalDoc $this->init(); if (!$this->oldInstance) { $this->logger->logger('Shutting down MadelineProto ('.static::class.')'); + $this->destructing = true; if ($this->API) { $this->API->destructing = true; $this->API->unreference(); } - $this->destructing = true; if (isset($this->wrapper)) { + $this->logger->logger('Prompting final serialization...'); Tools::wait($this->wrapper->serialize()); + $this->logger->logger('Done final serialization!'); } if ($this->unlock) { ($this->unlock)(); diff --git a/src/danog/MadelineProto/Async/AsyncConstruct.php b/src/danog/MadelineProto/Async/AsyncConstruct.php index ba1fa6ae..d12b402b 100644 --- a/src/danog/MadelineProto/Async/AsyncConstruct.php +++ b/src/danog/MadelineProto/Async/AsyncConstruct.php @@ -34,7 +34,7 @@ class AsyncConstruct /** * Async init promise. * - * @var Promise + * @var Promise|null|boolean */ private $asyncInitPromise; /** @@ -93,10 +93,9 @@ class AsyncConstruct $this->asyncInitPromise = Tools::call($promise); $this->asyncInitPromise->onResolve( function (?\Throwable $error, $result): void { - if ($error) { - throw $error; + if (!$error) { + $this->asyncInitPromise = null; } - $this->asyncInitPromise = null; } ); } diff --git a/src/danog/MadelineProto/CombinedEventHandler.php b/src/danog/MadelineProto/CombinedEventHandler.php deleted file mode 100644 index 1b670f0e..00000000 --- a/src/danog/MadelineProto/CombinedEventHandler.php +++ /dev/null @@ -1,59 +0,0 @@ -. - * - * @author Daniil Gentili - * @copyright 2016-2020 Daniil Gentili - * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3 - * - * @link https://docs.madelineproto.xyz MadelineProto documentation - */ - -namespace danog\MadelineProto; - -abstract class CombinedEventHandler -{ - private $CombinedAPI; - public function __construct($CombinedAPI) - { - $this->CombinedAPI = $CombinedAPI; - foreach ($CombinedAPI->instances as $path => $instance) { - $this->referenceInstance($path); - } - } - final public function __sleep() - { - $keys = \method_exists($this, '__magic_sleep') ? $this->__magic_sleep() : \get_object_vars($this); - unset($keys['CombinedAPI']); - if (isset($this->CombinedAPI) && $this->CombinedAPI instanceof CombinedAPI) { - foreach ($this->CombinedAPI->instance_paths as $path) { - unset($keys[$path]); - } - } else { - foreach ($keys as $key => $value) { - if ($value instanceof API && $key === $value->session) { - unset($keys[$key]); - } - } - } - return \array_keys($keys); - } - final public function referenceInstance($path) - { - $this->{$path} = $this->CombinedAPI->instances[$path]; - } - final public function removeInstance($path) - { - if (isset($this->{$path})) { - unset($this->{$path}); - } - } -} diff --git a/src/danog/MadelineProto/Ipc/IpcState.php b/src/danog/MadelineProto/Ipc/IpcState.php index d792da6f..73cf6bdb 100644 --- a/src/danog/MadelineProto/Ipc/IpcState.php +++ b/src/danog/MadelineProto/Ipc/IpcState.php @@ -18,7 +18,7 @@ final class IpcState /** * Exception. */ - private ?\Throwable $exception; + private ?ExitFailure $exception; /** * Construct. * @@ -29,7 +29,7 @@ final class IpcState { $this->startupTime = \microtime(true); $this->startupId = $startupId; - $this->exception = $exception; + $this->exception = $exception ? new ExitFailure($exception) : null; } /** @@ -59,6 +59,6 @@ final class IpcState */ public function getException(): ?\Throwable { - return $this->exception; + return $this->exception ? $this->exception->getException() : null; } } diff --git a/src/danog/MadelineProto/Ipc/Runner/entry.php b/src/danog/MadelineProto/Ipc/Runner/entry.php index d34087d3..3aaae70d 100644 --- a/src/danog/MadelineProto/Ipc/Runner/entry.php +++ b/src/danog/MadelineProto/Ipc/Runner/entry.php @@ -98,11 +98,11 @@ use danog\MadelineProto\Tools; Magic::$script_cwd = $_GET['cwd'] ?? Magic::getcwd(); $API = new API($ipcPath, (new Ipc)->setForceFull(true)); + $API->init(); + $API->initSelfRestart(); while (true) { try { - $API->init(); - $API->initSelfRestart(); Tools::wait($session->storeIpcState(new IpcState($runnerId))); Tools::wait(Server::waitShutdown()); return; @@ -112,10 +112,15 @@ use danog\MadelineProto\Tools; } } } catch (\Throwable $e) { - Logger::log("Got exception $e in IPC server, exiting...", Logger::FATAL_ERROR); + Logger::log("$e", Logger::FATAL_ERROR); + Logger::log("Got exception in IPC server, exiting...", Logger::FATAL_ERROR); $ipc = Tools::wait($session->getIpcState()); if (!($ipc && $ipc->getStartupId() === $runnerId && !$ipc->getException())) { + Logger::log("Reporting error!"); Tools::wait($session->storeIpcState(new IpcState($runnerId, $e))); + Logger::log("Reported error!"); + } else { + Logger::log("Not reporting error!"); } } } diff --git a/src/danog/MadelineProto/MTProto.php b/src/danog/MadelineProto/MTProto.php index 7f74e328..a12509ca 100644 --- a/src/danog/MadelineProto/MTProto.php +++ b/src/danog/MadelineProto/MTProto.php @@ -504,8 +504,8 @@ class MTProto extends AsyncConstruct implements TLCallback if (!$this->session || $this->session instanceof MemoryArray) { return $data; } - yield $this->session['data'] = \serialize($data); - var_dump($this); + yield $this->session->offsetSet('data', $data); + var_dump("Saved!"); return $this->session; } @@ -981,7 +981,7 @@ class MTProto extends AsyncConstruct implements TLCallback while (yield $iterator->advance()) { [$id, $full] = $iterator->getCurrent(); if (isset($full['full'], $full['last_update'])) { - $this->full_chats[$id] = ['full' => $full['full'], 'last_update' => $full['last_update']]; + yield $this->full_chats->offsetSet($id, ['full' => $full['full'], 'last_update' => $full['last_update']]); } } @@ -1152,6 +1152,8 @@ class MTProto extends AsyncConstruct implements TLCallback foreach ($this->datacenter->getDataCenterConnections() as $datacenter) { $datacenter->disconnect(); } + $this->logger->logger("Unreferenced instance"); + } /** * Destructor. diff --git a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php index 8ee6a12e..ce1f2891 100644 --- a/src/danog/MadelineProto/MTProtoTools/PeerHandler.php +++ b/src/danog/MadelineProto/MTProtoTools/PeerHandler.php @@ -130,7 +130,7 @@ trait PeerHandler $user['access_hash'] = $existingChat['access_hash']; } } - $this->chats[$user['id']] = $user; + yield $this->chats->offsetSet($user['id'], $user); $this->cachePwrChat($user['id'], false, true); } $this->cacheChatUsername($user['id'], $user); @@ -159,7 +159,7 @@ trait PeerHandler $existingChat = yield $this->chats[-$chat['id']]; if (!$existingChat || $existingChat !== $chat) { $this->logger->logger("Updated chat -{$chat['id']}", \danog\MadelineProto\Logger::ULTRA_VERBOSE); - $this->chats[-$chat['id']] = $chat; + yield $this->chats->offsetSet(-$chat['id'], $chat); $this->cachePwrChat(-$chat['id'], $this->getSettings()->getPeer()->getFullFetch(), true); } $this->cacheChatUsername(-$chat['id'], $chat); @@ -197,7 +197,7 @@ trait PeerHandler } $chat = $newchat; } - $this->chats[$bot_api_id] = $chat; + yield $this->chats->offsetSet($bot_api_id, $chat); $fullChat = yield $this->full_chats[$bot_api_id]; if ($this->getSettings()->getPeer()->getFullFetch() && (!$fullChat || $fullChat['full']['participants_count'] !== (yield from $this->getFullInfo($bot_api_id))['full']['participants_count'])) { $this->cachePwrChat($bot_api_id, $this->getSettings()->getPeer()->getFullFetch(), true); diff --git a/src/danog/MadelineProto/Magic.php b/src/danog/MadelineProto/Magic.php index 0583822e..051a6a58 100644 --- a/src/danog/MadelineProto/Magic.php +++ b/src/danog/MadelineProto/Magic.php @@ -58,6 +58,10 @@ class Magic * @var boolean */ public static $isFork = false; + /** + * Whether this is an IPC worker + */ + public static bool $isIpcWorker = false; /** * Whether we can get our PID. * @@ -230,6 +234,7 @@ class Magic // Setup error reporting \set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']); \set_exception_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionHandler']); + self::$isIpcWorker = defined(\MADELINE_WORKER_TYPE::class) ? \MADELINE_WORKER_TYPE === 'madeline-ipc' : false; if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') { try { \error_reporting(E_ALL); @@ -261,11 +266,11 @@ class Magic \pcntl_signal(SIGINT, SIG_DFL); Loop::unreference(Loop::onSignal(SIGINT, static function () { Logger::log('Got sigint', Logger::FATAL_ERROR); - Magic::shutdown(1); + Magic::shutdown(self::$isIpcWorker ? 0 : 1); })); Loop::unreference(Loop::onSignal(SIGTERM, static function () { Logger::log('Got sigterm', Logger::FATAL_ERROR); - Magic::shutdown(1); + Magic::shutdown(self::$isIpcWorker ? 0 : 1); })); } catch (\Throwable $e) { } diff --git a/src/danog/MadelineProto/Serialization.php b/src/danog/MadelineProto/Serialization.php index 409b202e..98fd45f4 100644 --- a/src/danog/MadelineProto/Serialization.php +++ b/src/danog/MadelineProto/Serialization.php @@ -195,7 +195,10 @@ abstract class Serialization if ($unserialized instanceof DriverArray) { Logger::log("Extracting session from database..."); yield from $unserialized->initConnection($unserialized->dbSettings); - $unserialized = \unserialize(yield $unserialized['data']); + $unserialized = yield $unserialized['data']; + if (!$unserialized) { + throw new Exception("Could not extract session from database!"); + } } } else { $unserialized = yield from self::legacyUnserialize($session->getLegacySessionPath()); diff --git a/tools/translator.php b/tools/translator.php index e472abeb..340e9699 100644 --- a/tools/translator.php +++ b/tools/translator.php @@ -60,13 +60,11 @@ $count = \count(Lang::$lang[$lang_code]); $curcount = 0; \ksort(Lang::$current_lang); foreach (Lang::$current_lang as $key => $value) { - if (!isset(Lang::$lang[$lang_code][$key])) { + if (!(Lang::$lang[$lang_code][$key] ?? '')) { Lang::$lang[$lang_code][$key] = $value; } - if (Lang::$lang[$lang_code][$key] === $value && ( - $lang_code !== 'en' || $value == '' - )) { + if (Lang::$lang[$lang_code][$key] === '' || (Lang::$lang[$lang_code][$key] === Lang::$lang['en'][$key] && Lang::$lang[$lang_code][$key] !== 'Bot')) { $value = Lang::$lang[$lang_code][$key]; if (\in_array($key, ['v_error', 'v_tgerror'])) { $value = \hex2bin($value);