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();
 }
 /**
  * 初始化并连接zookeeper,
  * 通过name和token认证用户权限
  * @param array $meta_params : zookeeper的参数集合
  * @return true on success or false on failure
  */
 public function init($name, $token, $meta_params)
 {
     // 检查name和token
     if (empty($name) || empty($token)) {
         BigpipeLog::fatal("[init][miss queue name or token]");
         return false;
     }
     $this->_queue_name = $name;
     $this->_queue_token = $token;
     // 通过conf准备meta
     // 检查meta配置
     if (!isset($meta_params['meta_host']) || !isset($meta_params['root_path'])) {
         BigpipeLog::fatal("[init][miss meta host or root path]");
         return false;
     }
     $this->_meta_host = $meta_params['meta_host'];
     $this->_root_path = $meta_params['root_path'];
     $this->_recv_timeo = $meta_params['zk_recv_timeout'];
     $this->_zk = new Zookeeper();
     // 实例并初始化meta manager
     /*
             $this->_meta_manager = new BigpipeMetaManager;
             if (false === $this->_meta_manager->init($meta_params))
             {
                 BigpipeLog::warning("[init][fail to init meta manager]");
                 return false;
                     } 
     */
     $this->_clean_meta_info();
     // 初始化connection
     if (false === $this->_zk->connect($this->_meta_host, null, $this->_recv_timeo)) {
         BigpipeLog::warning("[init][fail to connect to meta][host:%s]", $this->_meta_host);
         return false;
     }
     //置零update次数
     //        $this->_update_cnt = 0;
     $this->_inited = true;
     // init中不用从meta获取信息, 让用户主动调用update获取信息
     //         if (false === $this->update())
     //         {
     //             $this->_inited = false;
     //             return false;
     //         }
     return true;
 }
 private function _load_meta($meta_conf)
 {
     // 检查必须的配置项
     if (false === isset($meta_conf['meta_host']) || false === isset($meta_conf['root_path']) || false === isset($meta_conf['zk_recv_timeout'])) {
         BigpipeLog::fatal('[queue client configure][missing mandatory meta configure]');
         return false;
     }
     $this->meta = $meta_conf;
     return true;
 }
 private function _load_meta($meta_arr)
 {
     $meta_node = new BigpipeMetaConf();
     if (false === $meta_node->load($meta_arr)) {
         BigpipeLog::fatal('[%s:%u][%s][fail to load meta "meta" in configure]', __FILE__, __LINE__, __FUNCTION__);
         return false;
     }
     $this->meta = $meta_node->to_array();
     return true;
 }
 /**
  * 更新meta信息, 记录重试次数
  * @return boolean
  */
 private function _failover()
 {
     if ($this->_fo_count >= $this->_max_fo_cnt) {
         // 重置failover
         BigpipeLog::fatal("[_failover][can not do more][max_cnt:%d]", $this->_max_fo_cnt);
         $this->_fo_sleep_time = 0;
         $this->_fo_count = 0;
         return false;
     }
     if (0 == $this->_fo_sleep_time) {
         // php中只有微秒级的usleep和秒级的sleep
         // 目前只有当start时才会进入这个分支。
         // 这时我们会跳过failover
         $this->_fo_sleep_time = BigpipeCommonDefine::INIT_FO_SLEEP_TIME * 1000;
     } else {
         usleep($this->_fo_sleep_time);
     }
     // usleep($this->_fo_sleep_time);
     $this->_fo_count++;
     $this->_fo_sleep_time *= 2;
     // increase failover sleep time
     if ($this->_fo_sleep_time > BigpipeCommonDefine::MAX_FO_SLEEP_TIME) {
         // failover sleep time不能无限制增长
         $this->_fo_sleep_time = BigpipeCommonDefine::MAX_FO_SLEEP_TIME;
     }
     // 通过meta跟新stripe
     $broker = $this->_update_meta();
     if (false === $broker) {
         BigpipeLog::fatal("[_failover][can not update meta from meta agent]");
         return false;
     }
     // 连接broker
     $pub_dest = array("socket_address" => $broker['ip'], "socket_port" => $broker['port'], "socket_timeout" => $this->_conn_timeo);
     $this->_stomp_adapter->set_destination($pub_dest);
     $this->_stomp_adapter->role = BStompRoleType::PUBLISHER;
     $this->_stomp_adapter->topic_name = $broker['stripe'];
     $this->_stomp_adapter->session_id = $this->_session_id;
     // 发布时session不变
     if ($this->_stomp_adapter->connect()) {
         BigpipeLog::debug("[Success][connected on broker][ip:%s][port:%u]", $broker['ip'], $broker['port']);
         BigpipeLog::debug('[session message id][%u]', $this->_stomp_adapter->session_message_id);
         $this->_broker = $broker;
         return true;
     }
     return false;
     // 连接失败
 }
 /**
  * 更新meta信息, 记录重试次数
  * @return boolean
  */
 private function _failover()
 {
     // failover时, 订阅、发布状态无效,重置状态
     if (true == $this->_is_subscribed) {
         $this->_unsubscribe();
         // 先尝试取消订阅, 但是不用考虑错误 (因为failover中有错误是常态)
         $this->_is_subscribed = false;
     }
     if ($this->_fo_count > $this->_max_fo_cnt) {
         // 重置failover
         BigpipeLog::fatal("[%s:%u][%s][can not do more]", __FILE__, __LINE__, __FUNCTION__);
         $this->_fo_sleep_time = 0;
         $this->_fo_count = 0;
         return false;
     }
     if (0 == $this->_fo_sleep_time) {
         // 第一次flush subscribe时,我们往往不希望等待,
         // 因此这时跳过sleep过程
         // php中只有微秒级的usleep和秒级的sleep
         $this->_fo_sleep_time = BigpipeCommonDefine::INIT_FO_SLEEP_TIME * 1000;
     } else {
         usleep($this->_fo_sleep_time);
     }
     $this->_fo_count++;
     $this->_fo_sleep_time *= 2;
     // increase failover sleep time
     if ($this->_fo_sleep_time > BigpipeCommonDefine::MAX_FO_SLEEP_TIME) {
         // failover sleep time不能无限制增长
         $this->_fo_sleep_time = BigpipeCommonDefine::MAX_FO_SLEEP_TIME;
     }
     // 通过meta跟新stripe
     if (false === $this->_update_meta()) {
         BigpipeLog::fatal("[%s:%u][%s][can not update meta from meta agent]", __FILE__, __LINE__, __FUNCTION__);
         return false;
     }
     // 随机选择并连接一个broker
     $is_ok = false;
     do {
         $broker = $this->_random_select_broker();
         if (false === $broker) {
             // 无新broker可选, failover失败
             BigpipeLog::fatal("[%s:%u][%s][no broker to subcribe]", __FILE__, __LINE__, __FUNCTION__);
             break;
         }
         // try to connect to broker
         $sub_dest = array("socket_address" => $broker->ip, "socket_port" => $broker->port, "socket_timeout" => $this->_conn_timeo);
         $this->_stomp_adapter->set_destination($sub_dest);
         $this->_stomp_adapter->role = BStompRoleType::SUBSCRIBER;
         $this->_stomp_adapter->topic_name = $this->_stripe['stripe_name'];
         $this->_stomp_adapter->session_id = BigpipeUtilities::get_pipelet_name($this->_pipe_name, $this->_pipelet_id) . '_' . BigpipeUtilities::get_uid();
         if ($this->_stomp_adapter->connect()) {
             BigpipeLog::debug("[%s:%u][%s][Success][connected on broker][ip:%s][port:%u]", __FILE__, __LINE__, __FUNCTION__, $broker->ip, $broker->port);
             BigpipeLog::debug('[%s:%u][%s][session message id][smid:%s]', __FILE__, __LINE__, __FUNCTION__, $this->_stomp_adapter->session_message_id);
             $is_ok = true;
             break;
             // 跳出连接
         }
     } while (true);
     return $is_ok;
 }