1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-26 19:24:42 +01:00

Measure request latency in nanoseconds

This commit is contained in:
Daniil Gentili 2024-05-09 20:50:04 +02:00
parent be472eaadd
commit 746d88b852
7 changed files with 27 additions and 17 deletions

View File

@ -45,7 +45,7 @@ final class CheckLoop extends Loop
public function __construct(Connection $connection)
{
$this->initCommon($connection);
$this->resendTimeout = $this->API->settings->getRpc()->getRpcResendTimeout();
$this->resendTimeout = (int) ($this->API->settings->getRpc()->getRpcResendTimeout() * 1_000_000_000.0);
}
/**
* Main loop.
@ -113,7 +113,7 @@ final class CheckLoop extends Loop
$this->API->logger("Message $message received by server and was already processed, requesting reply...", Logger::ERROR);
$reply[] = $message_id;
} elseif ($chr & 32) {
if ($message->getSent() + $this->resendTimeout < time()) {
if ($message->getSent() + $this->resendTimeout < hrtime(true)) {
if ($message->isCancellationRequested()) {
unset($this->connection->new_outgoing[$message_id], $this->connection->outgoing_messages[$message_id]);
@ -143,7 +143,7 @@ final class CheckLoop extends Loop
} else {
foreach ($this->connection->new_outgoing as $message_id => $message) {
if ($message->wasSent()
&& $message->getSent() + $this->timeout < time()
&& $message->getSent() + $this->timeout < hrtime(true)
&& $message->unencrypted
) {
$this->API->logger("Still missing $message on DC {$this->datacenter}, resending", Logger::ERROR);

View File

@ -51,7 +51,7 @@ trait Common
/**
* Network-related timeouts.
*/
private float $timeout;
private int $timeout;
/**
* Constructor function.
*/
@ -61,6 +61,6 @@ trait Common
$this->connection = $connection;
$this->datacenter = $connection->getDatacenterID();
$this->shared = $connection->getShared();
$this->timeout = $this->shared->getSettings()->getTimeout();
$this->timeout = (int)($this->shared->getSettings()->getTimeout() * 1_000_000_000.0);
}
}

View File

@ -75,7 +75,7 @@ final class MTProtoIncomingMessage extends MTProtoMessage
$this->content = $content;
$this->msgId = $msgId;
$this->received = time();
$this->received = hrtime(true);
parent::__construct(!isset(MTProtoMessage::NOT_CONTENT_RELATED[$content['_']]));
if (!$this->contentRelated) {

View File

@ -158,7 +158,7 @@ class MTProtoOutgoingMessage extends MTProtoMessage
//throw new Exception("Trying to resend already replied message $this!");
}
$this->state |= self::STATE_SENT;
$this->sent = time();
$this->sent = hrtime(true);
if (isset($this->sendDeferred)) {
$sendDeferred = $this->sendDeferred;
$this->sendDeferred = null;
@ -332,7 +332,7 @@ class MTProtoOutgoingMessage extends MTProtoMessage
} elseif ($this->state & self::STATE_ACKED) {
$state = 'acked';
} elseif ($this->state & self::STATE_SENT) {
$state = 'sent '.(time() - $this->sent).' seconds ago';
$state = 'sent '.((hrtime(true) - $this->sent) / 1_000_000_000).' seconds ago';
} else {
$state = 'pending';
}

View File

@ -72,7 +72,7 @@ trait AckHandler
*/
public function hasPendingCalls(): bool
{
$timeout = $this->shared->getSettings()->getTimeout();
$timeout = (int) ($this->shared->getSettings()->getTimeout() * 1_000_000_000.0);
$pfs = $this->shared->getGenericSettings()->getAuth()->getPfs();
$unencrypted = !$this->shared->hasTempAuthKey();
$notBound = !$this->shared->isBound();
@ -80,7 +80,7 @@ trait AckHandler
/** @var MTProtoOutgoingMessage */
foreach ($this->new_outgoing as $message) {
if ($message->wasSent()
&& $message->getSent() + $timeout < time()
&& $message->getSent() + $timeout < hrtime(true)
&& $message->unencrypted === $unencrypted
&& $message->constructor !== 'msgs_state_req') {
if (!$unencrypted && $pfsNotBound && $message->constructor !== 'auth.bindTempAuthKey') {
@ -99,7 +99,7 @@ trait AckHandler
$settings = $this->shared->getSettings();
$global = $this->shared->getGenericSettings();
$dropTimeout = $global->getRpc()->getRpcDropTimeout();
$timeout = $settings->getTimeout();
$timeout = (int) ($settings->getTimeout() * 1_000_000_000.0);
$pfs = $global->getAuth()->getPfs();
$unencrypted = !$this->shared->hasTempAuthKey();
$notBound = !$this->shared->isBound();
@ -111,7 +111,7 @@ trait AckHandler
/** @var MTProtoOutgoingMessage $message */
foreach ($this->new_outgoing as $message_id => $message) {
if ($message->wasSent()
&& $message->getSent() + $timeout < time()
&& $message->getSent() + $timeout < hrtime(true)
&& $message->unencrypted === $unencrypted
) {
if (!$unencrypted && $pfsNotBound && $message->constructor !== 'auth.bindTempAuthKey') {
@ -121,7 +121,7 @@ trait AckHandler
unset($this->new_outgoing[$message_id], $this->outgoing_messages[$message_id]);
continue;
}
if ($message->getSent() + $dropTimeout < time()) {
if ($message->getSent() + $dropTimeout < hrtime(true)) {
$this->handleReject($message, static fn () => new TimeoutException('Request timeout'));
continue;
}

View File

@ -21,6 +21,7 @@ declare(strict_types=1);
namespace danog\MadelineProto\MTProtoSession;
use Amp\SignalException;
use danog\BetterPrometheus\BetterHistogram;
use danog\Loop\Loop;
use danog\MadelineProto\FileRedirect;
use danog\MadelineProto\Lang;
@ -43,6 +44,7 @@ use const PHP_EOL;
/**
* Manages responses.
*
* @property ?BetterHistogram $requestLatencies
* @internal
*/
trait ResponseHandler
@ -279,6 +281,10 @@ trait ResponseHandler
'error_message' => 'OK',
'error_code' => '200'
]);
$this->requestLatencies?->observe(
hrtime(true) - $request->getSent(),
['method' => $request->constructor]
);
}
EventLoop::queue($request->reply(...), $response);
@ -295,6 +301,10 @@ trait ResponseHandler
'error_message' => preg_replace('/\d+/', 'X', $response['error_message']),
'error_code' => (string) $response['error_code']
]);
$this->requestLatencies?->observe(
hrtime(true) - $request->getSent(),
['method' => $request->constructor]
);
}
if ($request->isMethod
&& $request->constructor !== 'auth.bindTempAuthKey'
@ -335,7 +345,7 @@ trait ResponseHandler
$this->API->logger("Resending $request due to {$response['error_message']}");
$this->gotResponseForOutgoingMessage($request);
$msgId = $request->getMsgId();
$request->setSent(time() + 5*60);
$request->setSent(hrtime(true) + (5*60 * 1_000_000_000));
$request->setMsgId(null);
$request->setSeqNo(null);
$prev = $request->previousQueuedMessage;
@ -387,7 +397,7 @@ trait ResponseHandler
$this->API->logger("Resending $request due to {$response['error_message']}");
$this->gotResponseForOutgoingMessage($request);
$msgId = $request->getMsgId();
$request->setSent(time() + 5*60);
$request->setSent(hrtime(true) + (5*60 * 1_000_000_000));
$request->setMsgId(null);
$request->setSeqNo(null);
\assert($msgId !== null);
@ -458,7 +468,7 @@ trait ResponseHandler
$this->API->logger("Flood, waiting $seconds seconds before repeating async call of $request...", Logger::NOTICE);
$this->gotResponseForOutgoingMessage($request);
$msgId = $request->getMsgId();
$request->setSent(time() + $seconds);
$request->setSent(hrtime(true) + ($seconds * 1_000_000_000));
$request->setMsgId(null);
$request->setSeqNo(null);
\assert($msgId !== null);

View File

@ -159,7 +159,7 @@ trait Session
if ($message->canGarbageCollect()) {
$count++;
} else {
$ago = time() - $message->getSent();
$ago = (hrtime(true) - $message->getSent()) / 1_000_000_000;
if ($ago > 2) {
$this->API->logger("Can't garbage collect $message in DC {$this->datacenter}, no response has been received or it wasn't yet handled!", Logger::VERBOSE);
}