【原创】利用Redis模拟简单队列工作
写得有点乱了,勿喷
/**
* @name RedisQueue
* @uses simulation queue work
* @author jiang kejun <jinhua_k9@163.com>
* @since 2013.08.27
* @version $Id: code.php 200 2013.08.27 create jkj $
* @example :
* # if(php_sapi_name()=='cli'){
# $rq1 = new RedisQueueServer("w1");
# $rq1->openService();
# }
*/
class RedisQueue
{
var $_redis = null;
var $_key = null;
var $_keyno = null;
var $retmsg = null;
// various states
const WAITING = 2;
const FINISHED = 3;
const ACCEPTING = 4;
const STOPING = 5;
const CALLING = 6;
function __construct(){
try{
$this->_redis = new Redis();
$this->_redis->connect('127.0.0.1', 6379, 10);
}catch(RedisException $r){
printf("The redis-server is not open or unable to connect [%s:%s]!
line:[%s]", '127.0.0.1', 6379, __LINE__ );
exit();
}
$this->_key = date("ymd");
$this->_keyno = $this->_key."_no";
if(!$this->_redis->exists($this->_keyno)){
// base number
$this->_redis->incrBy($this->_keyno, 100);
}
}
/**
* push a queue
* @access public
*
* @return bool
*/
function pushQueue(){
// push
$nr = $this->_redis->incr($this->_keyno);
$this->msgHelper(self::WAITING, $nr);
return $this->_redis->rPush($this->_key, $nr);
}
/**
* pop the current queue
* @access public
*
* @return void
*/
function popQueue(){
$this->_redis->lPop($this->_key);
}
/**
* queue length
*
* @return int
*/
function length(){
return $this->_redis->lSize($this->_key);
}
/**
* return message helper (log)
*
* @param int $type
* @param mixed $nr
* @return void
*/
function msgHelper($type, $nr){
switch($type){
case self::WAITING:
$array = array('error'=>0,'message'=>'no:'.$nr.';There are '.$this->length().' line up before!');
$this->retmsg = json_encode($array);
break;
case self::STOPING:
$array = array('error'=>1,'message'=>'stop all');
$this->retmsg = json_encode($array);
break;
case self::CALLING:
$array = array('error'=>0,'message'=>'Call transferred to deal with state after 5 seconds');
$this->retmsg = json_encode($array);
break;
case self::ACCEPTING:
$array = array('error'=>0,'message'=>'Is being dealt with business');
$this->retmsg = json_encode($array);
break;
default:
$array = array('error'=>2,'message'=>'unknown');
$this->retmsg = json_encode($array);
break;
}
}
/**
* flush all db (cache)
*
* @return void
*/
function flush(){
echo "clearing..\n";
$this->_redis->flushAll();
echo "ok\n";
}
function getQueueInfo(){
}
/**
* destroy
* @return void
*/
function __destruct(){
$this->_redis->close();
}
}
class RedisQueueServer extends RedisQueue
{
var $_current = null;
var $_service = null;
// processing state
const FINISHED = 1;
const SKIP = 2;
const WORKING = 0;
// init
function __construct($windowno){
parent::__construct();
$this->_service = $windowno;
echo "Window is open service...\n";
}
/**
* open service
*
* @return bool
*/
function openService(){
if(!$this->_redis->exists($this->_service)){
$this->_redis->hSet($this->_service, 'status', 1);
}
$i=0;
while($this->_current = $this->_redis->lGet($this->_key, 0 ))
{
$this->_redis->hSet($this->_service, $this->_current, self::WORKING);
$this->msgHelper(parent::CALLING, $this->_current);
echo "please ".$this->_current." to ".$this->_service." window transaction\n";
echo "input cmd:";
$cmd = trim(fgets(STDIN));
if($cmd == "1"){
echo $this->_current." is working\n";
$this->msgHelper(parent::ACCEPTING, $this->_current);
// skip
}elseif($cmd == "0"){
$this->popQueue();
$this->_redis->hSet($this->_service, $this->_current, self::SKIP);
$i++;
continue;
}
$cmd = trim(fgets(STDIN));
// finished
if($cmd == 'y'){
$this->popQueue();
$this->_redis->hSet($this->_service, $this->_current, self::FINISHED);
$this->msgHelper(parent::FINISHED, $this->_current);
$i++;
}elseif($cmd=='n'){
// quit
}elseif($cmd=='q'){
echo "Is out of the queue...\n";
exit();
}
sleep(2);
}
if($i){
echo "ok,You dealt with $i m of business success";
}else{
echo "is an empty queue";
}
//return false;
}
/**
* stop the current service
* return void
*/
function stop(){
$this->msgHelper(parent::STOPING, 0);
$this->_redis->hSet($this->_service, 'status', 2);
}
}
class RedisQueueClient extends RedisQueue
{
}