mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-30 04:08:59 +01:00
Improve performance
This commit is contained in:
parent
c5b7a06641
commit
cc4a99d598
@ -2,7 +2,7 @@ MadelineProto was updated (8.0.0-beta100)!
|
||||
|
||||
Features:
|
||||
- Thanks to the many translation contributors @ https://weblate.madelineproto.xyz/, MadelineProto is now fully localized in Hebrew, Persian, Kurdish, Uzbek and Italian, with WIP translations in Russian and French!
|
||||
- You can now use callFork to fork a new green thread!
|
||||
- You can now use `Tools::callFork` to fork a new green thread!
|
||||
- The `waveform` attribute of `Voice` objects is now automatically encoded and decoded to an array of 100 integer values!
|
||||
- Added a custom PeerNotInDbException class for "This peer is not present in the internal peer database" errors
|
||||
- Added a `label` property to the Button class, directly indicating the button label (instead of manually fetching it as an array key).
|
||||
@ -13,7 +13,7 @@ Features:
|
||||
|
||||
|
||||
Fixes:
|
||||
- Fixed file uploads with uv
|
||||
- Fixed file uploads with ext-uv!
|
||||
- Many performance improvements and bugfixes!
|
||||
- Improve background broadcasting with the broadcast API using a pre-defined list of `whitelist` IDs!
|
||||
- Broadcast IDs are now unique across multiple broadcasts, even if previous broadcasts already completed their ID will never be re-used.
|
||||
|
@ -18,16 +18,11 @@
|
||||
* @link https://docs.madelineproto.xyz MadelineProto documentation
|
||||
*/
|
||||
|
||||
use Amp\Http\Server\HttpServer;
|
||||
use danog\MadelineProto\API;
|
||||
use danog\MadelineProto\APIWrapper;
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\FileCallback;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\MTProtoTools\Files;
|
||||
use danog\MadelineProto\RPCErrorException;
|
||||
use danog\MadelineProto\Settings;
|
||||
use danog\MadelineProto\Tools;
|
||||
use League\Uri\Contracts\UriException;
|
||||
|
||||
/*
|
||||
@ -79,7 +74,7 @@ class MyEventHandler extends EventHandler
|
||||
* @var array
|
||||
*/
|
||||
private $states = [];
|
||||
public function onStart()
|
||||
public function onStart(): void
|
||||
{
|
||||
$this->adminId = $this->getInfo(self::ADMIN)['bot_api_id'];
|
||||
}
|
||||
@ -88,7 +83,7 @@ class MyEventHandler extends EventHandler
|
||||
*
|
||||
* @param array $update Update
|
||||
*/
|
||||
public function onUpdateNewChannelMessage(array $update)
|
||||
public function onUpdateNewChannelMessage(array $update): void
|
||||
{
|
||||
//$this->onUpdateNewMessage($update);
|
||||
}
|
||||
@ -154,7 +149,7 @@ class MyEventHandler extends EventHandler
|
||||
|
||||
$url = new FileCallback(
|
||||
$url,
|
||||
function ($progress, $speed, $time) use ($peerId, $id) {
|
||||
function ($progress, $speed, $time) use ($peerId, $id): void {
|
||||
$this->logger("Upload progress: $progress%");
|
||||
|
||||
static $prev = 0;
|
||||
|
@ -23,6 +23,7 @@ namespace danog\MadelineProto;
|
||||
use Amp\DeferredFuture;
|
||||
use Amp\Future;
|
||||
use Amp\Sync\LocalMutex;
|
||||
use Closure;
|
||||
use danog\MadelineProto\Db\DbPropertiesTrait;
|
||||
use danog\MadelineProto\EventHandler\Filter\Combinator\FiltersAnd;
|
||||
use danog\MadelineProto\EventHandler\Filter\Filter;
|
||||
@ -123,15 +124,26 @@ abstract class EventHandler extends AbstractAPI
|
||||
$methods = [];
|
||||
$handlers = [];
|
||||
$has_any = false;
|
||||
$basic_handler = static function (array $update, Closure $closure): void {
|
||||
$r = $closure($update);
|
||||
if ($r instanceof Generator) {
|
||||
Tools::consumeGenerator($r);
|
||||
}
|
||||
};
|
||||
foreach ((new ReflectionClass($this))->getMethods(ReflectionMethod::IS_PUBLIC) as $methodRefl) {
|
||||
$method = $methodRefl->getName();
|
||||
if ($method === 'onAny') {
|
||||
$has_any = true;
|
||||
continue;
|
||||
}
|
||||
$closure = $this->$method(...);
|
||||
$method_name = \lcfirst(\substr($method, 2));
|
||||
if (($constructor = $constructors->findByPredicate($method_name)) && $constructor['type'] === 'Update') {
|
||||
$methods[$method_name] = $this->$method(...);
|
||||
$methods[$method_name] = [
|
||||
function (array $update) use ($basic_handler, $closure): void {
|
||||
$basic_handler($update, $closure);
|
||||
}
|
||||
];
|
||||
continue;
|
||||
}
|
||||
if (!($handler = $methodRefl->getAttributes(Handler::class))) {
|
||||
@ -149,61 +161,17 @@ abstract class EventHandler extends AbstractAPI
|
||||
Filter::fromReflectionType($methodRefl->getParameters()[0]->getType())
|
||||
);
|
||||
$filter = $filter->initialize($this) ?? $filter;
|
||||
$handlers []= [
|
||||
$method,
|
||||
$handler,
|
||||
$filter
|
||||
];
|
||||
}
|
||||
$prevClosure = null;
|
||||
/** @var Filter $filter */
|
||||
foreach ($handlers as [$method, $handler, $filter]) {
|
||||
$closure = $this->$method(...);
|
||||
if ($prevClosure) {
|
||||
$prevClosure = function (Update $update) use ($prevClosure, $closure, $filter): void {
|
||||
if ($filter->apply($update)) {
|
||||
EventLoop::queue($closure, $update);
|
||||
}
|
||||
$prevClosure();
|
||||
};
|
||||
} else {
|
||||
$prevClosure = function (Update $update) use ($closure, $filter): void {
|
||||
if ($filter->apply($update)) {
|
||||
EventLoop::queue($closure, $update);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
if ($prevClosure) {
|
||||
foreach (['updateNewMessage', 'updateNewChannelMessage'] as $update) {
|
||||
if (isset($methods[$update])) {
|
||||
$old = $methods[$update];
|
||||
$methods[$update] = function (array $update) use ($old, $prevClosure): void {
|
||||
$obj = $this->wrapUpdate($update);
|
||||
if ($obj === null) {
|
||||
$r = $old($update);
|
||||
if ($r instanceof Generator) {
|
||||
Tools::consumeGenerator($r);
|
||||
}
|
||||
} else {
|
||||
$prevClosure($obj);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
$methods[$update] = function (array $update) use ($prevClosure): void {
|
||||
$obj = $this->wrapUpdate($update);
|
||||
if ($obj !== null) {
|
||||
$prevClosure($obj);
|
||||
}
|
||||
};
|
||||
$handlers []= function (Update $update) use ($closure, $filter): void {
|
||||
if ($filter->apply($update)) {
|
||||
EventLoop::queue($closure, $update);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
if ($has_any) {
|
||||
$onAny = $this->onAny(...);
|
||||
foreach ($constructors->by_id as $constructor) {
|
||||
if ($constructor['type'] === 'Update' && !isset($methods[$constructor['predicate']])) {
|
||||
$methods[$constructor['predicate']] = $onAny;
|
||||
$methods[$constructor['predicate']] = [$onAny];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,27 +181,16 @@ abstract class EventHandler extends AbstractAPI
|
||||
foreach ($plugins as $class => $_) {
|
||||
$plugin = $pluginsPrev[$class] ?? $pluginsNew[$class] ?? new $class;
|
||||
$pluginsNew[$class] = $plugin;
|
||||
foreach ($plugin->internalStart($MadelineProto, $pluginsPrev, $pluginsNew, false) ?? [] as $update => $method) {
|
||||
if (isset($methods[$update])) {
|
||||
$oldMethod = $methods[$update];
|
||||
$methods[$update] = function (array $update) use ($oldMethod, $method): void {
|
||||
EventLoop::queue(function () use ($update, $method): void {
|
||||
$r = $method($update);
|
||||
if ($r instanceof Generator) {
|
||||
Tools::consumeGenerator($r);
|
||||
}
|
||||
});
|
||||
$r = $oldMethod($update);
|
||||
if ($r instanceof Generator) {
|
||||
Tools::consumeGenerator($r);
|
||||
}
|
||||
};
|
||||
}
|
||||
[$newMethods, $newHandlers] = $plugin->internalStart($MadelineProto, $pluginsPrev, $pluginsNew, false) ?? [];
|
||||
foreach ($newMethods as $update => $method) {
|
||||
$methods[$update] ??= [];
|
||||
$methods[$update][] = $method;
|
||||
}
|
||||
$handlers = \array_merge($handler, $newHandlers);
|
||||
}
|
||||
|
||||
$this->startedInternal = true;
|
||||
return $methods;
|
||||
return [$methods, $handlers];
|
||||
} finally {
|
||||
$this->startDeferred = null;
|
||||
$startDeferred->complete();
|
||||
|
@ -63,7 +63,7 @@ abstract class Message extends AbstractMessage
|
||||
public readonly bool $imported;
|
||||
|
||||
/** For Public Service Announcement messages, the PSA type */
|
||||
public readonly string $psaType;
|
||||
public readonly ?string $psaType;
|
||||
|
||||
// Todo media (photosizes, thumbs), albums, reactions, replies, games eventually
|
||||
|
||||
|
@ -590,7 +590,7 @@ trait PeerHandler
|
||||
* type: string
|
||||
* } : ($type is API::INFO_TYPE_TYPE ? string : ($type is \danog\MadelineProto\API::INFO_TYPE_ID ? int : array{_: string, user_id?: int, access_hash?: int, min?: bool, chat_id?: int, channel_id?: int}|array{_: string, user_id?: int, access_hash?: int, min?: bool}|array{_: string, channel_id: int, access_hash: int, min: bool})))
|
||||
*/
|
||||
public function getInfo(mixed $id, int $type = \danog\MadelineProto\API::INFO_TYPE_ALL): array|int
|
||||
public function getInfo(mixed $id, int $type = \danog\MadelineProto\API::INFO_TYPE_ALL): array|int|string
|
||||
{
|
||||
if (\is_array($id)) {
|
||||
switch ($id['_']) {
|
||||
@ -722,7 +722,7 @@ trait PeerHandler
|
||||
* type: string
|
||||
* }&array) : array|int)
|
||||
*/
|
||||
private function genAll($constructor, $folder_id, int $type): array|int
|
||||
private function genAll($constructor, $folder_id, int $type): array|int|string
|
||||
{
|
||||
if ($type === \danog\MadelineProto\API::INFO_TYPE_CONSTRUCTOR) {
|
||||
if ($constructor['_'] === 'user') {
|
||||
|
@ -49,10 +49,8 @@ use danog\MadelineProto\RPCErrorException;
|
||||
use danog\MadelineProto\Settings;
|
||||
use danog\MadelineProto\TL\TL;
|
||||
use danog\MadelineProto\TL\Types\Button;
|
||||
use danog\MadelineProto\Tools;
|
||||
use danog\MadelineProto\UpdateHandlerType;
|
||||
use danog\MadelineProto\VoIP;
|
||||
use Generator;
|
||||
use Revolt\EventLoop;
|
||||
use Throwable;
|
||||
use Webmozart\Assert\Assert;
|
||||
@ -87,6 +85,7 @@ trait UpdateHandler
|
||||
$this->event_handler = null;
|
||||
$this->event_handler_instance = null;
|
||||
$this->eventHandlerMethods = [];
|
||||
$this->eventHandlerHandlers = [];
|
||||
$this->pluginInstances = [];
|
||||
$this->startUpdateSystem();
|
||||
}
|
||||
@ -109,6 +108,7 @@ trait UpdateHandler
|
||||
$this->event_handler = null;
|
||||
$this->event_handler_instance = null;
|
||||
$this->eventHandlerMethods = [];
|
||||
$this->eventHandlerHandlers = [];
|
||||
$this->pluginInstances = [];
|
||||
$this->startUpdateSystem();
|
||||
}
|
||||
@ -124,7 +124,7 @@ trait UpdateHandler
|
||||
$update = $update['progress'];
|
||||
}
|
||||
if ($f = $this->event_handler_instance->waitForInternalStart()) {
|
||||
$this->logger->logger("Postponing update handling, onStart is still running (if stuck here for too long, make sure to fork long-running tasks in onStart using EventLoop::queue to fix this)...", Logger::NOTICE);
|
||||
$this->logger->logger("Postponing update handling, onStart is still running (if stuck here for too long, make sure to fork long-running tasks in onStart using \$this->callFork(function () { ... }) to fix this)...", Logger::NOTICE);
|
||||
$this->updates[$this->updates_key++] = $update;
|
||||
$f->map(function (): void {
|
||||
\array_map($this->handleUpdate(...), $this->updates);
|
||||
@ -133,12 +133,18 @@ trait UpdateHandler
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!isset($this->eventHandlerMethods[$update['_']])) {
|
||||
return;
|
||||
if (isset($this->eventHandlerMethods[$update['_']])) {
|
||||
foreach ($this->eventHandlerMethods[$update['_']] as $closure) {
|
||||
$closure($update);
|
||||
}
|
||||
}
|
||||
$r = $this->eventHandlerMethods[$update['_']]($update);
|
||||
if ($r instanceof Generator) {
|
||||
Tools::consumeGenerator($r);
|
||||
if (\count($this->eventHandlerHandlers) !== 0) {
|
||||
$update = $this->wrapUpdate($update);
|
||||
if ($update !== null) {
|
||||
foreach ($this->eventHandlerHandlers as $closure) {
|
||||
$closure($update);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,6 +210,7 @@ trait UpdateHandler
|
||||
$this->event_handler = null;
|
||||
$this->event_handler_instance = null;
|
||||
$this->eventHandlerMethods = [];
|
||||
$this->eventHandlerHandlers = [];
|
||||
$this->pluginInstances = [];
|
||||
|
||||
[
|
||||
|
@ -56,6 +56,12 @@ trait Events
|
||||
* @var array<string, callable>
|
||||
*/
|
||||
private array $eventHandlerMethods = [];
|
||||
/**
|
||||
* Event handler handler list.
|
||||
*
|
||||
* @var array<string, callable>
|
||||
*/
|
||||
private array $eventHandlerHandlers = [];
|
||||
|
||||
/** @var array<class-string<EventHandler>, EventHandler> */
|
||||
private array $pluginInstances = [];
|
||||
@ -87,7 +93,7 @@ trait Events
|
||||
// Already started event handler
|
||||
return;
|
||||
}
|
||||
$this->eventHandlerMethods = $methods;
|
||||
[$this->eventHandlerMethods, $this->eventHandlerHandlers] = $methods;
|
||||
$this->pluginInstances = $pluginsNew;
|
||||
|
||||
$this->updateHandlerType = UpdateHandlerType::EVENT_HANDLER;
|
||||
@ -130,6 +136,7 @@ trait Events
|
||||
$this->event_handler = null;
|
||||
$this->event_handler_instance = null;
|
||||
$this->eventHandlerMethods = [];
|
||||
$this->eventHandlerHandlers = [];
|
||||
$this->pluginInstances = [];
|
||||
$this->setNoop();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user