mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-06-09 21:24:53 +00:00
Throttle resource pack sending using ack receipts
this isn't the best solution, as it limits the download speed somewhat, but it's relatively simple and works quite well. closes #3127
This commit is contained in:
parent
4abc36275c
commit
b9a1ef1357
@ -50,11 +50,22 @@ use function substr;
|
|||||||
* packs to the client.
|
* packs to the client.
|
||||||
*/
|
*/
|
||||||
class ResourcePacksPacketHandler extends PacketHandler{
|
class ResourcePacksPacketHandler extends PacketHandler{
|
||||||
private const PACK_CHUNK_SIZE = 128 * 1024; //128KB
|
private const PACK_CHUNK_SIZE = 256 * 1024; //256KB
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Larger values allow downloading more chunks at the same time, increasing download speed, but the client may choke
|
||||||
|
* and cause the download speed to drop (due to ACKs taking too long to arrive).
|
||||||
|
*/
|
||||||
|
private const MAX_CONCURRENT_CHUNK_REQUESTS = 1;
|
||||||
|
|
||||||
/** @var bool[][] uuid => [chunk index => hasSent] */
|
/** @var bool[][] uuid => [chunk index => hasSent] */
|
||||||
private array $downloadedChunks = [];
|
private array $downloadedChunks = [];
|
||||||
|
|
||||||
|
/** @phpstan-var \SplQueue<array{ResourcePack, int}> */
|
||||||
|
private \SplQueue $requestQueue;
|
||||||
|
|
||||||
|
private int $activeRequests = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @phpstan-param \Closure() : void $completionCallback
|
* @phpstan-param \Closure() : void $completionCallback
|
||||||
*/
|
*/
|
||||||
@ -62,7 +73,9 @@ class ResourcePacksPacketHandler extends PacketHandler{
|
|||||||
private NetworkSession $session,
|
private NetworkSession $session,
|
||||||
private ResourcePackManager $resourcePackManager,
|
private ResourcePackManager $resourcePackManager,
|
||||||
private \Closure $completionCallback
|
private \Closure $completionCallback
|
||||||
){}
|
){
|
||||||
|
$this->requestQueue = new \SplQueue();
|
||||||
|
}
|
||||||
|
|
||||||
public function setUp() : void{
|
public function setUp() : void{
|
||||||
$resourcePackEntries = array_map(function(ResourcePack $pack) : ResourcePackInfoEntry{
|
$resourcePackEntries = array_map(function(ResourcePack $pack) : ResourcePackInfoEntry{
|
||||||
@ -176,8 +189,38 @@ class ResourcePacksPacketHandler extends PacketHandler{
|
|||||||
$this->downloadedChunks[$packId][$packet->chunkIndex] = true;
|
$this->downloadedChunks[$packId][$packet->chunkIndex] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->session->sendDataPacket(ResourcePackChunkDataPacket::create($packId, $packet->chunkIndex, $offset, $pack->getPackChunk($offset, self::PACK_CHUNK_SIZE)));
|
$this->requestQueue->enqueue([$pack, $packet->chunkIndex]);
|
||||||
|
$this->processChunkRequestQueue();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function processChunkRequestQueue() : void{
|
||||||
|
if($this->activeRequests >= self::MAX_CONCURRENT_CHUNK_REQUESTS || $this->requestQueue->isEmpty()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @var ResourcePack $pack
|
||||||
|
* @var int $chunkIndex
|
||||||
|
*/
|
||||||
|
[$pack, $chunkIndex] = $this->requestQueue->dequeue();
|
||||||
|
|
||||||
|
$packId = $pack->getPackId();
|
||||||
|
$offset = $chunkIndex * self::PACK_CHUNK_SIZE;
|
||||||
|
$chunkData = $pack->getPackChunk($offset, self::PACK_CHUNK_SIZE);
|
||||||
|
$this->activeRequests++;
|
||||||
|
$this->session
|
||||||
|
->sendDataPacketWithReceipt(ResourcePackChunkDataPacket::create($packId, $chunkIndex, $offset, $chunkData))
|
||||||
|
->onCompletion(
|
||||||
|
function() use ($packId, $chunkIndex) : void{
|
||||||
|
$this->activeRequests--;
|
||||||
|
$this->processChunkRequestQueue();
|
||||||
|
},
|
||||||
|
function() : void{
|
||||||
|
//this may have been rejected because of a disconnection - this will do nothing in that case
|
||||||
|
$this->disconnectWithError("Plugin interrupted sending of resource packs");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$this->session->getLogger()->debug("Sent resource pack $packId chunk $chunkIndex");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user