Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions PHPDaemon/Clients/Redis/AutoScan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php
namespace PHPDaemon\Clients\Redis;

use PHPDaemon\Core\Daemon;
use PHPDaemon\Core\Debug;
use PHPDaemon\Core\CallbackWrapper;

/**
* @package NetworkClients
* @subpackage RedisClient
* @author Efimenko Dmitriy <ezheg89@gmail.com>
*/
class AutoScan {
use \PHPDaemon\Traits\ClassWatchdog;
use \PHPDaemon\Traits\StaticObjectWatchdog;

protected $conn;

protected $cmd;

protected $cursor = 0;

protected $args;

protected $limit = false;

protected $num = 0;

protected $isFreeze = false;

protected $cb;

protected $cbEnd;

/**
* Constructor
* @param Pool $pool Redis pool or connection
* @param string $cmd Command
* @param array $args Arguments
* @param cllable $cbEnd Callback
* @param integer $limit Limit
*/
public function __construct($pool, $cmd, $args = [], $cbEnd = null, $limit = false) {
$this->conn = $pool;
$this->cmd = $cmd;
$this->args = empty($args) ? [] : $args;
$this->limit = $limit;
if (is_numeric($this->args[0])) {
array_shift($this->args);
}
for ($i = sizeof($this->args) - 1; $i >= 0; --$i) {
$a = $this->args[$i];
if ((is_array($a) || is_object($a)) && is_callable($a)) {
$this->cb = CallbackWrapper::wrap($a);
$this->args = array_slice($this->args, 0, $i);
break;
}
elseif ($a !== null) {
break;
}
}
if ($cbEnd !== null) {
$this->cbEnd = CallbackWrapper::wrap($cbEnd);
}
$this->doIteration();
}

public function freeze() {
$this->isFreeze = true;
}

public function run() {
$this->isFreeze = false;
$this->doIteration();
}

public function reset() {
$this->num = 0;
$this->isFreeze = false;
}

protected function doIteration() {
if ($this->isFreeze) {
return;
}

$args = $this->args;
array_unshift($args, $this->cursor);
$args[] = function($redis) {
$this->conn = $redis;
$this->cursor = $redis->result[0];
call_user_func($this->cb, $redis);

if (!is_numeric($redis->result[0]) || !$redis->result[0] || ($this->limit && ++$this->num > $this->limit)) {
call_user_func($this->cbEnd, $redis, $this);
return;
}
$this->doIteration();
};
call_user_func_array([$this->conn, $this->cmd], $args);
}
}
12 changes: 12 additions & 0 deletions PHPDaemon/Clients/Redis/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,18 @@ public function meval($cb = null) {
return new MultiEval($cb, $this);
}

/**
* Wrapper for scans commands
* @param string $cmd Command
* @param array $args Arguments
* @param cllable $cbEnd Callback
* @param integer $limit Limit
* @return AutoScan
*/
public function autoscan($cmd, $args = [], $cbEnd = null, $limit = null) {
return new AutoScan($this, $cmd, $args, $cbEnd, $limit);
}

/**
* @TODO
* @param string $chan
Expand Down
51 changes: 51 additions & 0 deletions PHPDaemon/Clients/Redis/Examples/Scan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* `phpd.conf`
* Clients\Redis\Examples\Scan {}
*/
namespace PHPDaemon\Clients\Redis\Examples;

use PHPDaemon\Core\Daemon;
use PHPDaemon\Core\Debug;

/**
* @package NetworkClients
* @subpackage RedisClientExample
* @author Efimenko Dmitriy <ezheg89@gmail.com>
*/
class Scan extends \PHPDaemon\Core\AppInstance {
/**
* @var Pool
*/
public $redis;

/**
* Called when the worker is ready to go
* @return void
*/
public function onReady() {
$this->redis = \PHPDaemon\Clients\Redis\Pool::getInstance();

$params = [];
foreach (range(0, 100) as $i) {
$params[] = 'myset' . $i;
$params[] = 'value' . $i;
}
$params[] = function($redis) {
$params = [function($redis) {
D('Count: ' . count($redis->result[1]) . '; Next: ' . $redis->result[0]);
}];

$cbEnd = function($redis, $scan) {
D('Full scan end!');
};

// test 1
// call_user_func_array([$this->redis, 'scan'], $params);

// test 2
$this->redis->autoscan('scan', $params, $cbEnd, 50);
};
call_user_func_array([$this->redis, 'mset'], $params);
}
}
12 changes: 12 additions & 0 deletions PHPDaemon/Clients/Redis/Pool.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ public function meval($cb = null) {
return new MultiEval($cb, $this);
}

/**
* Wrapper for scans commands
* @param string $cmd Command
* @param array $args Arguments
* @param cllable $cbEnd Callback
* @param integer $limit Limit
* @return AutoScan
*/
public function autoscan($cmd, $args = [], $cbEnd = null, $limit = null) {
return new AutoScan($this, $cmd, $args, $cbEnd, $limit);
}

/**
* Setting default config options
* Overriden from NetworkClient::getConfigDefaults
Expand Down