public function testAllInOne()
 {
     // ²âÊÔ´òÓ¡µ½ÆÁÄ»
     BigpipeLog::debug('[%s:%u][%s][debug]', __FILE__, __LINE__, __FUNCTION__);
     BigpipeLog::trace('[%s:%u][%s][trace]', __FILE__, __LINE__, __FUNCTION__);
     BigpipeLog::notice('[%s:%u][%s][notice]', __FILE__, __LINE__, __FUNCTION__);
     BigpipeLog::monitor('[%s:%u][%s][monitor]', __FILE__, __LINE__, __FUNCTION__);
     BigpipeLog::warning('[%s:%u][%s][warning]', __FILE__, __LINE__, __FUNCTION__);
     BigpipeLog::fatal('[%s:%u][%s][fatal]', __FILE__, __LINE__, __FUNCTION__);
     // ²âÊÔ²»Êä³ö´òÓ¡ÐÅÏ¢log configure
     $conf = new BigpipeLogConf();
     $conf->severity = BigpipeLogSeverity::FATAL;
     $conf->disable_ostream = true;
     $fatal_log = sprintf('[%s:%u][%s][fatal message]', __FILE__, __LINE__, __FUNCTION__);
     $warning_Log = sprintf('[%s:%u][%s][warning]', __FILE__, __LINE__, __FUNCTION__);
     $this->assertTrue(BigpipeLog::init($conf));
     BigpipeLog::fatal('%s', $fatal_log);
     $msg = BigpipeLog::get_last_error_message();
     BigpipeLog::warning('%s', $warning_Log);
     $this->assertEquals($msg, BigpipeLog::get_last_error_message());
     $new_fatal_log = sprintf('[%s:%u][%s][fatal new message]', __FILE__, __LINE__, __FUNCTION__);
     $this->assertTrue($msg == BigpipeLog::get_last_error_message());
     // ²âÊÔclose
     BigpipeLog::close();
 }
 /**
  * 删除一个stop状态的queue
  * @param string $name        : name of the queue
  * @param string $token       : token of the queue
  * @param array  $meta_params : meta配置信息
  * @return boolean
  */
 public static function delete_queue($name, $token, $meta_params)
 {
     // 参数检查
     if (false === is_array($meta_params) || true === empty($name) || true === empty($token)) {
         BigpipeLog::fatal("[%s:%u][%s][invalid params]", __FILE__, __LINE__, __FUNCTION__);
         return false;
     }
     $meta = true === self::$unittest ? self::$stub_meta : self::_init_meta($meta_params);
     if (false === $meta) {
         BigpipeLog::fatal("[%s:%u][%s][fail to init meta]", __FILE__, __LINE__, __FUNCTION__);
         return false;
     }
     // 读取queue entry信息
     $full_entry = sprintf('queue/%s', $name);
     $stat = array('version' => 'for test');
     //仅在测试时有用
     $queue_info = $meta->get_entry($full_entry, $stat);
     if (false === $queue_info) {
         BigpipeLog::fatal("[%s:%u][%s][can not access to queue under /%s]", __FILE__, __LINE__, __FUNCTION__, $full_entry);
         return false;
     }
     if ($token != $queue_info['token']) {
         BigpipeLog::fatal("[%s:%u][%s][wrong token][entry:%s]", __FILE__, __LINE__, __FUNCTION__, $full_entry);
         return false;
     }
     $status = $queue_info['status'];
     if (BigpipeQueueStatus::STOPPED != $status) {
         // 只删除stop状态的queue node
         BigpipeLog::warning("[%s:%u][%s][please stop the queue before delete it][entry:%s][status:%s]", __FILE__, __LINE__, __FUNCTION__, $full_entry, BigpipeQueueStatus::to_string($status));
         return false;
     }
     $curr_version = $stat['version'];
     $queue_info['status'] = BigpipeQueueStatus::STOPPED;
     // change status of a queue
     $ret = $meta->delete_entry($full_entry);
     if (false === $ret) {
         BigpipeLog::fatal("[%s:%u][%s][fail to delete the queue][name:%s][ver:%u]", __FILE__, __LINE__, __FUNCTION__, $name, $curr_version);
         return false;
     }
     BigpipeLog::notice("[%s:%u][%s][queue is deleted][name:%s]", __FILE__, __LINE__, __FUNCTION__, $name);
     return true;
 }
 /**
  * 从zk中读取一个node并,反序列化node value数组
  * @return mixed value of a node. <p>
  *         return value converted into associative arrays on success. <p>
  *         return false on failure
  */
 public function deserialize($buff)
 {
     // unpack head
     $this->_content = $buff;
     $head_arr = unpack("C1ver/C1len/S1flags/L1bdlen", $this->_content);
     $this->_version = $head_arr['ver'];
     $this->_length = $head_arr['len'];
     $this->_flags = $head_arr['flags'];
     $this->_body_len = $head_arr['bdlen'];
     $obj = json_decode(substr($this->_content, $this->_length), true);
     if (null === $obj) {
         BigpipeLog::warning("[%s:%u][%s][fail to decode meta node][ver:%d][flags:%u][len:%u]", __FILE__, __LINE__, __FUNCTION__, $this->_version, $this->_flags, $this->_body_len);
         $obj = false;
     } else {
         BigpipeLog::notice("[%s:%u][%s][meta node header][ver:%d][flags:%u][len:%u]", __FILE__, __LINE__, __FUNCTION__, $this->_version, $this->_flags, $this->_body_len);
     }
     return $obj;
 }
 /**
  * 更新一个meta node的值
  * @param string $path    : 节点全路径(含root)
  * @param mixed  $value   : 需要更新的值
  * @param number $version : 原来节点的版本
  * @return true on success, or false on failure
  */
 public function update($path, $value, $version)
 {
     if (false === $this->_inited) {
         BigpipeLog::warning("[%s:%u][%s][uninited]", __FILE__, __LINE__, __FUNCTION__);
         return false;
     }
     if ($version < 0) {
         // zookeeper中version == -1表示强制更新节点
         // 这里我们不允许有这种操作
         BigpipeLog::warning("[%s:%u][%s][invalid version][ver:%d]", __FILE__, __LINE__, __FUNCTION__, $version);
         return false;
     }
     // set value
     $ret = null;
     if (false === $this->exists($path)) {
         BigpipeLog::notice("[%s:%u][%s][node does not exist][path:%s]", __FILE__, __LINE__, __FUNCTION__, $path);
     } else {
         // get version of old node
         $ret = $this->_zk->set($path, $value, $version);
     }
     if (null === $ret) {
         BigpipeLog::warning("[%s:%u][%s][fail to update node][path:%s][ver:%u]", __FILE__, __LINE__, __FUNCTION__, $path, $version);
         $ret = false;
     }
     return $ret;
 }
 /**
  * 发布一条消息
  * @param BigpipeMessagePackage $msg_pacakge
  * @return BigpipePubResult on success or false on failure
  */
 public function send($msg_package)
 {
     if (!$this->_is_started) {
         BigpipeLog::warning("[connection is not established][pipelet:%d]", $this->_pipelet_id);
         return false;
     }
     // 发送CONNECT
     $cmd = new BStompSendFrame();
     if (!$msg_package->store($cmd->message_body)) {
         // 包错误,不用考虑failover了
         BigpipeLog::warning("[fail to store message body]");
         return false;
     }
     if (true === $this->_last_send_ok) {
         // 当上次发送成功才增加session mesage id
         // 否则message id不变,防止重复发送
         $this->_session_msg_id++;
     }
     $cmd->destination = $this->_get_stripe_name();
     // echo "[stripe name][$cmd->destination]<br>";
     $cmd->no_dedupe = $this->_no_dedupe;
     $cmd->session_id = $this->_session_id;
     $cmd->session_message_id = $this->_session_msg_id;
     $cmd->receipt_id = isset($this->unittest) ? 'fake-receipt-id' : BigpipeUtilities::gen_receipt_id();
     if ($this->_enable_checksum) {
         // 发送message包校验
         $cmd->last_checksum = $this->_last_sign;
         $sign = creat_sign_mds64($cmd->message_body);
         $cmd->cur_checksum = $sign[2];
         // 注意函数返回值
         $this->_last_sign = $cmd->cur_checksum;
     }
     // 进入发送流程,
     // 发送失败则进入failover流程,直到failover失败。
     $send_result = false;
     do {
         if (false === $this->_stomp_adapter->send($cmd)) {
             BigpipeLog::warning("[send message error][session:%s][session_msg_id:%u]", $cmd->session_id, $cmd->session_message_id);
             continue;
         }
         $send_result = $this->_check_ack($cmd->receipt_id, $send_result);
         if (false === $send_result) {
             // ACK失败
             // 不用考虑BMQ_E_COMMAND_DUPLICATEMSG, 去重在broker做,
             // 用户不会收到duplicate返回.
             BigpipeLog::warning("[send message ack error][session:%s][session_msg_id:%u]", $cmd->session_id, $cmd->session_message_id);
             continue;
         } else {
             BigpipeLog::notice("[send message success][pipelet:%u][session:%s][session_msg_id:%u]", $this->_pipelet_id, $cmd->session_id, $cmd->session_message_id);
             break;
             // 发布成功
         }
     } while ($this->_failover());
     if (false !== $send_result) {
         $this->_active();
         // 清理failover状态
     } else {
         $this->_last_send_ok = false;
     }
     return $send_result;
 }