1
0
mirror of https://github.com/danog/MadelineProto.git synced 2025-01-23 05:51:14 +01:00

Gracefully handle IPC server restarts

This commit is contained in:
Daniil Gentili 2023-01-29 17:05:53 +01:00
parent e2392db86c
commit 4d0bfbc343
3 changed files with 21 additions and 18 deletions

View File

@ -42,15 +42,9 @@ abstract class ClientAbstract
/** /**
* Requests promise array. * Requests promise array.
* *
* @var array<DeferredFuture> * @var array<int, list{string|int, array|Wrapper, DeferredFuture}>
*/ */
private array $requests = []; private array $requests = [];
/**
* Wrappers array.
*
* @var array<Wrapper>
*/
private array $wrappers = [];
/** /**
* Whether to run loop. * Whether to run loop.
*/ */
@ -97,11 +91,10 @@ abstract class ClientAbstract
if (!isset($this->requests[$id])) { if (!isset($this->requests[$id])) {
Logger::log("Got response for non-existing ID $id!"); Logger::log("Got response for non-existing ID $id!");
} else { } else {
$promise = $this->requests[$id]; [, $args, $promise] = $this->requests[$id];
unset($this->requests[$id]); unset($this->requests[$id]);
if (isset($this->wrappers[$id])) { if ($args instanceof Wrapper) {
$this->wrappers[$id]->disconnect(); $args->disconnect();
unset($this->wrappers[$id]);
} }
if ($payload instanceof ExitFailure) { if ($payload instanceof ExitFailure) {
$promise->error($payload->getException()); $promise->error($payload->getException());
@ -121,6 +114,14 @@ abstract class ClientAbstract
try { try {
Server::startMe($this->session)->await(); Server::startMe($this->session)->await();
$this->server = connect($this->session->getIpcPath()); $this->server = connect($this->session->getIpcPath());
$requests = $this->requests;
$this->requests = [];
$this->id = 0;
foreach ($requests as [$function, $arguments, $deferred]) {
$id = $this->id++;
$this->requests[$id] = [$function, $arguments, $deferred];
$this->server->send([$function, $arguments]);
}
} catch (Throwable $e) { } catch (Throwable $e) {
Logger::log("Got exception while reconnecting in IPC client: $e"); Logger::log("Got exception while reconnecting in IPC client: $e");
} }
@ -137,8 +138,10 @@ abstract class ClientAbstract
{ {
$this->run = false; $this->run = false;
$this->server->disconnect(); $this->server->disconnect();
foreach ($this->wrappers as $w) { foreach ($this->requests as [, $args, $promise]) {
$w->disconnect(); if ($args instanceof Wrapper) {
$args->disconnect();
}
} }
} }
/** /**
@ -149,10 +152,9 @@ abstract class ClientAbstract
*/ */
public function __call(string|int $function, array|Wrapper $arguments) public function __call(string|int $function, array|Wrapper $arguments)
{ {
$this->requests[$this->id++] = $deferred = new DeferredFuture; $deferred = new DeferredFuture;
if ($arguments instanceof Wrapper) { $id = $this->id++;
$this->wrappers[\count($this->requests) - 1] = $arguments; $this->requests[$id] = [$function, $arguments, $deferred];
}
$this->server->send([$function, $arguments]); $this->server->send([$function, $arguments]);
return $deferred->getFuture()->await(); return $deferred->getFuture()->await();
} }

View File

@ -65,6 +65,8 @@ use Webmozart\Assert\Assert;
$paths = [ $paths = [
dirname(__DIR__, 5).'/autoload.php', dirname(__DIR__, 5).'/autoload.php',
dirname(__DIR__, 3).'/vendor/autoload.php', dirname(__DIR__, 3).'/vendor/autoload.php',
dirname(__DIR__, 7).'/autoload.php',
dirname(__DIR__, 5).'/vendor/autoload.php',
]; ];
foreach ($paths as $path) { foreach ($paths as $path) {

View File

@ -53,7 +53,6 @@ trait DialogHandler
$lock = $this->cachingAllBotUsers->acquire(); $lock = $this->cachingAllBotUsers->acquire();
try { try {
while (true) { while (true) {
$this->logger($this->botDialogsUpdatesState);
$result = $this->methodCallAsyncRead( $result = $this->methodCallAsyncRead(
'updates.getDifference', 'updates.getDifference',
[ [