PHP code example of pudongping / hyperf-wise-locksmith
1. Go to this page and download the library: Download pudongping/hyperf-wise-locksmith library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
pudongping / hyperf-wise-locksmith example snippets
declare(strict_types=1);
namespace App\Controller;
use Hyperf\HttpServer\Annotation\AutoController;
use App\Services\AccountBalanceService;
use Hyperf\Coroutine\Parallel;
use function \Hyperf\Support\make;
#[AutoController]
class BalanceController extends AbstractController
{
// curl '127.0.0.1:9511/balance/consumer?type=noMutex'
public function consumer()
{
$type = $this->request->input('type', 'noMutex');
$amount = (float)$this->request->input('amount', 1);
$parallel = new Parallel();
$balance = make(AccountBalanceService::class);
// 模拟 20 个并发
for ($i = 1; $i <= 20; $i++) {
$parallel->add(function () use ($balance, $i, $type, $amount) {
return $balance->runLock($i, $type, $amount);
}, $i);
}
$result = $parallel->wait();
return $this->response->json($result);
}
}
declare(strict_types=1);
namespace App\Services;
use Hyperf\Contract\StdoutLoggerInterface;
use Pudongping\HyperfWiseLocksmith\Locker;
use Pudongping\WiseLocksmith\Exception\WiseLocksmithException;
use Pudongping\WiseLocksmith\Support\Swoole\SwooleEngine;
use Throwable;
class AccountBalanceService
{
/**
* 用户账户初始余额
*
* @var float|int
*/
private float|int $balance = 10;
public function __construct(
private StdoutLoggerInterface $logger,
private Locker $locker
) {
$this->locker->setLogger($logger);
}
private function deductBalance(float|int $amount)
{
if ($this->balance >= $amount) {
// 模拟业务处理耗时
usleep(500 * 1000);
$this->balance -= $amount;
}
return $this->balance;
}
/**
* @return float
*/
private function getBalance(): float
{
return $this->balance;
}
public function runLock(int $i, string $type, float $amount)
{
try {
$start = microtime(true);
switch ($type) {
case 'flock':
$this->flock($amount);
break;
case 'redisLock':
$this->redisLock($amount);
break;
case 'redLock':
$this->redLock($amount);
break;
case 'channelLock':
$this->channelLock($amount);
break;
case 'noMutex':
default:
$this->deductBalance($amount);
break;
}
$balance = $this->getBalance();
$id = SwooleEngine::id();
$cost = microtime(true) - $start;
$this->logger->notice('[{type} {cost}] ==> [{i}<=>{id}] ==> 当前用户的余额为:{balance}', compact('type', 'i', 'balance', 'id', 'cost'));
return $balance;
} catch (WiseLocksmithException|Throwable $e) {
return sprintf('Err Msg: %s ====> %s', $e, $e->getPrevious());
}
}
private function flock(float $amount)
{
$path = BASE_PATH . '/runtime/alex.lock.cache';
$fileHandler = fopen($path, 'a+');
// fwrite($fileHandler, sprintf("%s - %s \r\n", 'Locked', microtime()));
$res = $this->locker->flock($fileHandler, function () use ($amount) {
return $this->deductBalance($amount);
});
return $res;
}
private function redisLock(float $amount)
{
$res = $this->locker->redisLock('redisLock', function () use ($amount) {
return $this->deductBalance($amount);
}, 10);
return $res;
}
private function redLock(float $amount)
{
$res = $this->locker->redLock('redLock', function () use ($amount) {
return $this->deductBalance($amount);
}, 10);
return $res;
}
private function channelLock(float $amount)
{
$res = $this->locker->channelLock('channelLock', function () use ($amount) {
return $this->deductBalance($amount);
});
return $res;
}
}
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.