1
0
mirror of https://github.com/danog/MadelineProto.git synced 2025-01-23 10:31:13 +01:00

Improve cancellation

This commit is contained in:
Daniil Gentili 2023-08-14 19:17:50 +02:00
parent cb06c5879c
commit bd1d23062d
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
3 changed files with 28 additions and 25 deletions

View File

@ -471,7 +471,6 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getconfig-array-config-array" name="getConfig">Get cached (or eventually re-fetch) server-side config: getConfig</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getcachedconfig-array" name="getCachedConfig">Get cached server-side config: getCachedConfig</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getcallstate-int-id-danog-madelineproto-voip-callstate" name="getCallState">Get call state: getCallState</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#callstatus-int-id-danog-madelineproto-voip-callstate" name="callStatus">Get call status: callStatus</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getEmojiKeywordsDifference.html" name="messages.getEmojiKeywordsDifference">Get changed emoji keywords »: messages.getEmojiKeywordsDifference</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/help.getAppChangelog.html" name="help.getAppChangelog">Get changelog of current app. : help.getAppChangelog</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/stats.getBroadcastStats.html" name="stats.getBroadcastStats">Get channel statistics: stats.getBroadcastStats</a>
@ -554,6 +553,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/payments.getPaymentReceipt.html" name="payments.getPaymentReceipt">Get payment receipt: payments.getPaymentReceipt</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getPeerSettings.html" name="messages.getPeerSettings">Get peer settings: messages.getPeerSettings</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/phone.getCallConfig.html" name="phone.getCallConfig">Get phone call configuration to be passed to libtgvoip's shared config: phone.getCallConfig</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getcall-int-id-danog-madelineproto-voip" name="getCall">Get phone call information: getCall</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getPinnedDialogs.html" name="messages.getPinnedDialogs">Get pinned dialogs: messages.getPinnedDialogs</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getPollVotes.html" name="messages.getPollVotes">Get poll results for non-anonymous polls: messages.getPollVotes</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getPollResults.html" name="messages.getPollResults">Get poll results: messages.getPollResults</a>
@ -581,9 +581,9 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/stats.getMegagroupStats.html" name="stats.getMegagroupStats">Get supergroup statistics: stats.getMegagroupStats</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getTmpPassword.html" name="account.getTmpPassword">Get temporary payment password: account.getTmpPassword</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.getAdminLog.html" name="channels.getAdminLog">Get the admin log of a channel/supergroup: channels.getAdminLog</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getcallbypeer-int-userid-danog-madelineproto-voip" name="getCallByPeer">Get the call with the specified user ID: getCallByPeer</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getSearchCounters.html" name="messages.getSearchCounters">Get the number of results that would be found by a messages.search call with the same parameters: messages.getSearchCounters</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.getParticipants.html" name="channels.getParticipants">Get the participants of a supergroup/channel: channels.getParticipants</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getcallbypeer-int-userid-danog-madelineproto-voip" name="getCallByPeer">Get the phone call with the specified user ID: getCallByPeer</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getbroadcastprogress-int-id-danog-madelineproto-broadcast-progress" name="getBroadcastProgress">Get the progress of a currently running broadcast: getBroadcastProgress</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getTheme.html" name="account.getTheme">Get theme information: account.getTheme</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/channels.getForumTopics.html" name="channels.getForumTopics">Get topics of a forum: channels.getForumTopics</a>
@ -847,6 +847,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/contacts.blockFromReplies.html" name="contacts.blockFromReplies">Stop getting notifications about thread replies of a certain user in @replies: contacts.blockFromReplies</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/phone.leaveGroupCallPresentation.html" name="phone.leaveGroupCallPresentation">Stop screen sharing in a group call: phone.leaveGroupCallPresentation</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#stop-void" name="stop">Stop update loop: stop</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#stopplay-int-id-void" name="stopPlay">Stops playing all files in the call, clears the main and the hold playlist: stopPlay</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getcdnconfig-void" name="getCdnConfig">Store RSA keys for CDN datacenters: getCdnConfig</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/payments.validateRequestedInfo.html" name="payments.validateRequestedInfo">Submit requested order information for validation: payments.validateRequestedInfo</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/phone.toggleGroupCallStartSubscription.html" name="phone.toggleGroupCallStartSubscription">Subscribe or unsubscribe to a scheduled group call: phone.toggleGroupCallStartSubscription</a>
@ -900,6 +901,7 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.confirmPasswordEmail.html" name="account.confirmPasswordEmail">Verify an email to use as 2FA recovery method: account.confirmPasswordEmail</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.searchSentMedia.html" name="messages.searchSentMedia">View and search recently sent media. : messages.searchSentMedia</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.sendVote.html" name="messages.sendVote">Vote in a poll: messages.sendVote</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#skipplay-int-id-void" name="skipPlay">When called, skips to the next file in the playlist: skipPlay</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.updateDeviceLocked.html" name="account.updateDeviceLocked">When client-side passcode lock feature is enabled, will not show message texts in incoming PUSH notifications: account.updateDeviceLocked</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#fullchatlastupdated-mixed-id-int" name="fullChatLastUpdated">When was full info for this chat last cached: fullChatLastUpdated</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getContactSignUpNotification.html" name="account.getContactSignUpNotification">Whether the user will receive notifications when contacts sign up: account.getContactSignUpNotification</a>

View File

@ -1314,11 +1314,11 @@ abstract class InternalDoc
/**
* Provide a buffered reader for a file, URL or amp stream.
*
* @return Closure(int, ?Cancellation): ?string
* @return Closure(int): ?string
*/
public static function openBuffered(\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\Amp\ByteStream\ReadableStream $stream): \Closure
public static function openBuffered(\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\Amp\ByteStream\ReadableStream $stream, ?\Amp\Cancellation $cancellation = null): \Closure
{
return \danog\MadelineProto\Tools::openBuffered($stream);
return \danog\MadelineProto\Tools::openBuffered($stream, $cancellation);
}
/**
* Opens a file in append-only mode.

View File

@ -25,7 +25,6 @@ use Amp\CancelledException;
use Amp\DeferredCancellation;
use Amp\Pipeline\ConcurrentIterator;
use Amp\Pipeline\Queue;
use AssertionError;
use danog\Loop\GenericLoop;
use danog\MadelineProto\MTProtoTools\Crypt;
use danog\MadelineProto\VoIP\CallState;
@ -35,7 +34,6 @@ use danog\MadelineProto\VoIP\MessageHandler;
use danog\MadelineProto\VoIP\VoIPState;
use phpseclib3\Math\BigInteger;
use Revolt\EventLoop;
use SplQueue;
use Throwable;
use Webmozart\Assert\Assert;
@ -148,9 +146,9 @@ final class VoIPController
$this->public = new VoIP($API, $call);
$call['_'] = 'inputPhoneCall';
$this->packetQueue = new Queue(PHP_INT_MAX);
$this->packetIterator = $this->packetQueue->iterate();
$this->deferred = new DeferredCancellation;
$this->cancellation = $this->deferred->getCancellation();
$this->packetIterator = $this->packetQueue->iterate();
$this->playLoop = new GenericLoop($this->playLoop(...), "Play loop");
$this->call = $call;
if ($this->public->outgoing) {
@ -283,8 +281,8 @@ final class VoIPController
public function __serialize(): array
{
$data = \get_object_vars($this);
unset($data['cancellation']);
unset($data['deferred']);
unset($data['cancellation'], $data['deferred']);
$data['holdFiles'] = \array_filter(
$data['holdFiles'],
fn ($v) => !$v instanceof ReadableStream
@ -527,28 +525,31 @@ final class VoIPController
$it = new Ogg($pipe->getSource());
}
foreach ($it->opusPackets as $packet) {
$this->packetQueue->push($packet);
$this->packetQueue->pushAsync($packet)->await($this->cancellation);
}
}
private bool $muted = false;
private bool $playingHold = false;
private function playLoop(): void
{
while ($this->callState !== CallState::ENDED) {
$file = \array_shift($this->inputFiles);
if ($file) {
$this->playingHold = false;
} else {
$this->playingHold = true;
if (!$this->holdFiles) {
return;
}
$file = $this->holdFiles[($this->holdIndex++) % \count($this->holdFiles)];
while ($this->callState !== CallState::ENDED) {
$file = \array_shift($this->inputFiles);
if ($file) {
$this->playingHold = false;
} else {
$this->playingHold = true;
if (!$this->holdFiles) {
return;
}
try {
$this->startPlaying($file);
} catch (CancelledException) {}
$file = $this->holdFiles[($this->holdIndex++) % \count($this->holdFiles)];
}
try {
$this->startPlaying($file);
} catch (CancelledException) {
$this->packetQueue = new Queue(PHP_INT_MAX);
$this->packetIterator = $this->packetQueue->iterate();
}
}
}
private function pullPacket(): ?string
{
@ -649,9 +650,9 @@ final class VoIPController
public function skip(): void
{
$deferred = $this->deferred;
$deferred->cancel();
$this->deferred = new DeferredCancellation;
$this->cancellation = $this->deferred->getCancellation();
$deferred->cancel();
}
/**
* Stops playing all files, clears the main and the hold playlist.