joshdifabio/resource-pool

调节异步组件的并发级别

v0.2.0 2016-12-30 13:38 UTC

This package is auto-updated.

Last update: 2024-08-26 04:38:47 UTC


README

Build Status Coverage Code Quality

不要浪费资源,请进行资源池化!

简介

资源池允许您调节异步PHP组件的并发级别,从而减轻服务器的过载。如果您使用类似ReactPHP的库发送HTTP请求或创建子进程,您会发现它们特别有用。

基本用法

如果您不熟悉Promise,本节内容可能难以理解。

考虑一个异步发送HTTP请求到远程端点的应用程序。

function sendRequest($httpRequest) : PromiseInterface {
    // this would probably be something like Guzzle or React/HttpClient
}

您不应该这样做的方式

foreach (getThousandsOfRequests() as $request) {
    sendRequest($request)->then(function ($response) {
        // the response came back!
    });
}

// thousands of requests have been initiated concurrently

这种实现方式可能会在短时间内发送成百上千个请求,从而给远程服务器带来巨大负载,因为它试图响应您的请求。这实际上是一种DoS攻击,会让系统管理员哭泣,而您也会因此受到影响。

您应该这样做

创建一个表示固定数量资源的资源池,例如五个。

$pool = new \ResourcePool\Pool(5);

在发送请求之前,从池中分配一个资源。Pool::allocateOne()返回一个AllocationPromise,它会在资源可用时解析。

foreach (getThousandsOfRequests() as $request) {
    // to() will invoke a function and then release the allocated resources once it's done
    $pool->allocateOne()->to('sendRequest', $request)->then(function ($response) {
        // the response came back!
    });
}

// five requests are running; the rest are queued and will be sent as others complete

就这样!您做到了!这种实现方式将最多产生五个并发请求。

高级用法

高级用户?请继续阅读。

分配多个资源

$pool->allocate(5)->to(function () {
    // this task requires five resources to run!
});

分配所有资源

$pool->allocateAll()->to(function () {
    // this requires all the resources!
});

手动释放分配

// call then() instead of to() to work with the allocation directly
$pool->allocate(2)->then(function ($allocation) {
    // two things which need to run at the same time
    firstThing()->done([$allocation, 'releaseOne']);
    secondThing()->done([$allocation, 'releaseOne']);
});

强制立即解析分配

try {
    $allocation = $pool->allocate(2)->now();
} catch (\RuntimeException $e) {
    // throws a \RuntimeException if the pool cannot allocate two resources
}

您还可以选择在特定分配中超出池的大小。

$pool = new \ResourcePool\Pool(1);
$allocation = $pool->allocate(2)->force();
$pool->getUsage(); // 2
$pool->getAvailability(); // 0
$allocation->releaseAll();
$pool->getAvailability(); // 1

找出池何时空闲

$pool->whenNextIdle(function () {
    // the pool is idle!
});

更改池的大小

$pool->setSize(100);

找出已分配的资源数量

$pool->getUsage();

找出可用的资源数量

$pool->getAvailability();

安装

使用composer安装Resource Pool。

composer require joshdifabio/resource-pool

许可证

Resource Pool在MIT许可证下发布。