/** * 获取并发curl结果 * 为防止假死,设置循环最大执行时间,为0为不设最大执行时间 * @param int $max_timeout * @return array */ public function multiGet($max_timeout = 0) { $active = null; $t1 = time(); do { $mrc = curl_multi_exec($this->mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK) { if ($max_timeout > 0 && time() - $t1 > $max_timeout) { Lib_Log::warn("exec time out,exit loop"); break; } //PHP_VERSION_ID < 50214 ? usleep(5000) : curl_multi_select($this->mh, 0.2); if (curl_multi_select($this->mh, 0.2) != -1) { do { $mrc = curl_multi_exec($this->mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } $stat = array(); $data = array(); foreach ($this->handles as $key => $ch) { $d = array(); $d['errno'] = curl_errno($ch); if ($d['errno'] != CURLE_OK) { $d['error'] = curl_error($ch); continue; } else { $d['total_time'] = curl_getinfo($ch, CURLINFO_TOTAL_TIME); $d['code'] = curl_getinfo($ch, CURLINFO_HTTP_CODE); $d['data'] = curl_multi_getcontent($ch); } $data[$key] = $d; curl_multi_remove_handle($this->mh, $ch); curl_close($ch); } $this->handles = array(); return array('errno' => 0, 'data' => $data); }
/** * @param $callback * @return null|array * @throws Exception */ protected function _doAction($callback) { Lib_Log::debug(__METHOD__ . ': do action begin!'); if (empty($this->_currentDbName) || empty($this->_currentTableName)) { throw new Exception(__METHOD__ . 'empty param ! DB:' . var_export($this->_currentDbName, true) . ' Table: ' . var_export($this->_currentTableName, true), self::ERRNO_EMPTY_PARAMS); } Lib_Log::debug(__METHOD__ . ': data check finish!'); $doAct = function () use($callback) { $dbName = $this->_currentDbName; $tableName = $this->_currentTableName; if (empty($this->_conn->{$dbName})) { $this->ReConnect(); } $collection = $this->_conn->{$dbName}->{$tableName}; $ret = $callback($collection); return $ret; }; Lib_Log::debug(__METHOD__ . ': create function finish!'); $retryCount = self::RETRY_COUNT - 1; $ret = null; do { Lib_Log::debug(__METHOD__ . ': begin do action! retry count is: %d', $retryCount); try { $ret = $doAct(); $retryCount = -1; } catch (Exception $e) { if ($retryCount < 0) { throw new Exception($e->getMessage(), $e->getCode()); } else { Lib_Log::warn("MONGO Retry,retry time: %d, Exception code: %s, msg: %s", array(self::RETRY_COUNT - $retryCount, strval($e->getCode()), $e->getMessage())); } } } while (is_null($ret) && $retryCount-- >= 0); return $ret; }
/** * @param $callback * @param array $args */ function fork_count_processor($callback, $args) { $this->_counter_pid = pcntl_fork(); if ($this->_counter_pid < 0) { Lib_Log::warn("%s fork failed! result: %s", [__METHOD__, var_export($this->_counter_pid, true)]); $this->_counter_pid = null; } elseif ($this->_counter_pid == 0) { call_user_func_array($callback, $args); exit; } }
/** * @brief * 定时器,用来检测是否有子进程超时 * 同时增加超时控制 * @see * @note * @author duxin01 * @date 2014/04/17 13:32:38 **/ public function childAlarmHandler($signo) { foreach ($this->currentJobs as $pid => $startTime) { if (time() - $startTime < $this->childTimeout) { continue; } Lib_Log::warn("child timeout, kill -9 {$pid}"); $this->pushFaildData($pid); posix_kill($pid, SIGKILL); // clear pid of current jobs unset($this->currentJobs[$pid]); } pcntl_alarm($this->childTimeout); //重新设置闹钟 return true; }
/** * @param int $mid * @param array $stuff_mids * @param array $id_map * @return callable */ static function after_run_module_record_hook($mid, $stuff_mids, $id_map) { if ($stuff_mids === null) { $stuff_mids = []; } if (!isset($id_map[$mid][1])) { Lib_Log::warn("%s gen record id and order failed!", __METHOD__); } return function ($task_id, $module_id, $class, $result) use($mid, $stuff_mids, $id_map) { $record_id = $id_map[$mid][0]; $model_module_record = new Model_TaskRunModuleRecord(); // log for record Lib_Log::debug('record after hook task_id: [%d], module_id: [%d], record_id: [%d]', [$task_id, $module_id, $record_id]); // end log $stat = []; $end_time = time(); $counts = Module_ControlCentre_Counter::get_all_counts(); if (!isset($result['errno']) || $result['errno'] !== Const_Err_Base::ERR_OK) { $record = ['status' => Module_ModuleManager_Main::RUN_MODULE_STATUS_FAILED, 'result' => $result, 'end_time' => $end_time]; if (isset($result[Const_DataAccess::MREK_STATUS])) { $record['status'] = $result[Const_DataAccess::MREK_STATUS]; } } else { $record = ['status' => Module_ModuleManager_Main::RUN_MODULE_STATUS_FINISH, 'end_time' => $end_time]; $data = $result['data']; if (method_exists($class, 'format_record_msg')) { $stat = call_user_func([$class, 'format_record_msg'], $data); } if (!empty($stat)) { $record['result'] = ['errno' => Const_Err_Base::ERR_OK, 'msg' => $stat]; $record['stat'] = $stat; } } if ($counts['errno'] != Const_Err_Base::ERR_OK) { $stuff_mids = []; } else { $counts = $counts['data']; $_tmp_stat = Module_ControlCentre_Counter::formated_counts($mid, $counts); if (is_array($_tmp_stat) && !empty($_tmp_stat)) { $record['stat'] = isset($record['stat']) ? array_merge($_tmp_stat, $record['stat']) : $_tmp_stat; } unset($_tmp_stat); } $model_module_record->update_record($record_id, $record); foreach ($stuff_mids as $_mid) { $stat = []; $record_id = $id_map[$_mid][0]; $_tmp_stat = Module_ControlCentre_Counter::formated_counts($_mid, $counts); is_array($_tmp_stat) && ($stat = array_merge($_tmp_stat, $stat)); unset($_tmp_stat); $record = ['status' => Module_ModuleManager_Main::RUN_MODULE_STATUS_CALLED, 'end_time' => $end_time]; if (!empty($stat)) { $record['stat'] = $stat; } $model_module_record->update_record($record_id, $record); } }; }
/** * @param $action * @param $args * @return array|mixed|null */ protected function _do_action($action, $args) { $result = null; $falid_things = function ($result) use($action, $args) { Lib_Log::warn('REDIS-ACTION: ' . strtoupper($action) . ' FAILD, args: ' . json_encode($args) . ', result: ' . json_encode($result)); $this->_reconnect(); }; foreach (range(1, self::RETRY_COUNT) as $_count) { try { if (!$this->_redis || !$this->_is_connecting()) { $this->_create_connection(); } if (!$this->_redis || !$this->_is_connecting()) { $result = ['errno' => 1, 'data' => 'redis is not connected']; } else { $result = call_user_func_array([$this->_redis, $action], $args); $result = ['errno' => 0, 'data' => $result]; break; } } catch (RedisException $ex) { try { $falid_things([$ex->getCode(), $ex->getMessage(), 'retry count: ' . $_count]); } catch (RedisException $ex) { Lib_Log::warn("Redis reconnect failed, err: %s", json_encode($ex)); } $result = ['errno' => $ex->getCode(), 'data' => $ex->getMessage()]; } } return $result; }