/** * Launch a job from the job queue */ protected function launch_job($job_id, $task, $callback) { $pid = pcntl_fork(); if ($pid == -1) { cy_log(CY_ERROR, 'Could not launch new job, exiting'); return false; } else { if ($pid) { // Parent process // Sometimes you can receive a signal to the childSignalHandler function before this code executes if // the child script executes quickly enough! $this->current_jobs[$pid] = $job_id; // In the event that a signal for this pid was caught before we get here, it will be in our signalQueue array // So let's go ahead and process it now as if we'd just received the signal if (isset($this->signal_queue[$pid])) { $this->child_signal_handler(SIGCHLD, $pid, $this->signal_queue[$pid]); unset($this->signal_queue[$pid]); } } else { $exit_status = 0; call_user_func($callback, $task); exit($exit_status); } } return true; }
function run($client) { $errno = 0; $display = 'json'; $ret = $this->nshead->nshead_read($client); if (!$ret) { $errno = CYE_PARAM_ERROR; $error = 'nshead_read error'; goto error; } if ($ret['body_len'] == 0) { return array('errno' => CYE_DATA_EMPTY); } if (!($r = json_decode($ret['buf'], true))) { $errno = CYE_PARAM_ERROR; $error = 'request is not json'; goto error; } if (!isset($r['module']) || !isset($r['id'])) { $errno = CYE_PARAM_ERROR; $error = 'request has no module or id'; goto error; } $options = isset($r['query']) ? $r['query'] : []; $_ENV['module'] = $module = $r['module']; $_ENV['id'] = $id = $r['id']; $_ENV['method'] = $method = isset($r['method']) ? $r['method'] : 'get'; $_ENV['display'] = $display = isset($r['display']) ? $r['display'] : 'json'; $_ENV['version'] = $version = isset($r['version']) ? $r['version'] : 1; $classname = 'CY_App_' . $version . '_' . $module; if (!method_exists($classname, $method)) { $errno = CYE_PARAM_ERROR; $error = "method is not exists {$classname}:{$method}"; goto error; } $eny = new $classname(); $dt = $eny->get($id, $options, $_ENV); unset($eny); response: switch ($display) { case 'json': $body = json_encode($dt); break; //case 'mcpack': // $body = mc_pack_array2pack($dt); break; } $hdr = array('body_len' => strlen($body)); $this->nshead->nshead_write($client, $hdr, $body); return array('errno' => $errno); error: $dt = array('errno' => $errno, 'error' => $error); cy_log(CYE_WARNING, "{$client} " . $error); goto response; }
function mix($ch, $c) { $d = curl_getinfo($ch); $errno = curl_errno($ch); $error = curl_error($ch); if ($errno != CURLE_OK || !empty($error)) { $d['error'] = $error; cy_log(CYE_WARNING, '%s errno(%s) %s', $d['url'], $errno, $error); //cy_ctl_fail($this->hosts[$key], $_SERVER['REQUEST_TIME']); goto end; } if (isset($d['download_content_length'])) { $dcl = $d['download_content_length']; if ($dcl != -1 && $dcl != 0 && $dcl != $d['size_download']) { $d['error'] = 'not finish, maybe timeout is too small.'; cy_log(CYE_WARNING, '%s not finish, time cost %fs', $d['url'], $d['total_time']); goto end; } } $contents = curl_multi_getcontent($ch); $options = $c->options(); if (isset($options['include'])) { $header = substr($contents, 0, $d['header_size']); $contents = substr($contents, $d['header_size']); $headers = []; $array = explode("\n", $header); foreach ($array as $i => $h) { $h = explode(':', $h, 2); if (isset($h[1])) { $headers[$h[0]] = trim($h[1]); } } if (isset($array[0]) && preg_match('/.*(\\d\\d\\d).*/', $array[0], $m)) { $headers['Response Code'] = $m[1]; } $d['headers'] = $headers; } $d['data'] = $c->outputs($contents); $d['class'] = get_class($c); $d['proxy'] = isset($options['proxy']) ? $options['proxy'] : ''; end: curl_multi_remove_handle($this->mh, $ch); curl_close($ch); unset($this->handles[(int) $ch]); $this->count--; $d['errno'] = $errno; return $d; }
static function http_read($stream, $options) { static $length = 4096; $array = []; stream_set_blocking($stream, 1); $n_blank_line = 0; $size = 0; $buf = fgets($stream, $length); if (!$buf) { return array('errno' => -1); } $array[] = $buf; $header = []; do { if (($buf = fgets($stream, $length)) === false) { $id = (int) $stream; cy_log(CYE_ERROR, $options['server'] . ' http_read error'); return array('errno' => CYE_NET_ERROR); } $pair = explode(":", $buf, 2); if (isset($pair[1])) { $header[strtolower($pair[0])] = trim($pair[1]); } $array[] = $buf; } while ($buf !== "\r\n" && $buf !== NULL && !feof($stream)); if (isset($header['content-length'])) { $size = (int) $header['content-length']; } $data = implode("", $array); if ($buf !== NULL && $size) { $options['size'] = $size; $dt = self::default_read($stream, $options); if ($dt['errno'] === 0) { $data .= $dt['data']; } } return array('errno' => 0, 'data' => $data); }
function prepare($key, $req) { if (empty($req['server'])) { return false; } if (empty($req['body'])) { return false; } /* if(!cy_ctl_check($req['server'], $_SERVER['REQUEST_TIME'])) { cy_log(CYE_WARNING, $req['server']." net_prepare server ".$req['server']." is blocked."); return false; } */ $to = $_ENV['config']['timeout']['net_default']; isset($req['timeout']) || ($req['timeout'] = (int) $to); isset($req['timeout_s']) || ($req['timeout_s'] = ($to - (int) $to) * 1000000); $flags = STREAM_CLIENT_ASYNC_CONNECT | STREAM_CLIENT_CONNECT; $host = $this->protocol . $req['server']; $stream = stream_socket_client($host, $errno, $error, 1, $flags); if (!$stream) { cy_log(CYE_ERROR, 'stream_socket_client errno ' . $errno . " " . $error); return false; } $req['status'] = 0; $req['key'] = $key; /* set no block. */ stream_set_blocking($stream, 0); stream_set_timeout($stream, $req['timeout'], $req['timeout_s']); /* add task */ $id = (int) $stream; $this->sockets[$id] = $stream; $this->tasks[$id] = $req; return true; }
function rc_read($stream, $options) { static $max_line_size = 512; if (($str = fgets($stream, $max_line_size)) == false) { goto error; } $data = array(); $nums = (int) substr($str, 1); $size = 0; stream_set_blocking($stream, 1); while ($size++ < $nums) { if (($str = fgets($stream, $max_line_size)) == false) { goto error; } $len = (int) substr($str, 1); if ($len > 0) { $left = $len + 2; $str = ''; do { if (($p = fread($stream, $left)) == false) { goto error; } $str .= $p; $left -= strlen($p); } while ($left > 0); $data[] = substr($str, 0, -2); } else { $data[] = NULL; } } return array('errno' => 0, 'data' => $data); error: $id = (int) $stream; cy_log(CYE_ERROR, $options['server'] . ' rc_read error fd: %d .', $id); return array('errno' => CYE_NET_ERROR, 'message' => $options['server'] . " read error."); }
function loop($callback) { while (true) { try { $this->callback = $callback; $this->queue->consume([$this, 'recv']); } catch (Exception $e) { cy_log(CYE_DEBUG, 'timeout or no new data.'); $this->connection->reconnect(); } } }
function run($client, $request = "") { $errno = 0; $error = ''; $display = 'json'; $b = cy_unpack($request, $this->config); if (!$b || empty($b['raw_header']) || empty($b['raw_len_head']) || $b['raw_len_head'] < 4) { $errno = CYE_PARAM_ERROR; $error = "invalid request."; goto error; } $r = cy_unpack($b['raw_header'], $this->config_head); $r['length'] = $b['raw_len_body']; $_ENV['module'] = $module = $r['module']; $_ENV['id'] = $id = $r['id']; $_ENV['method'] = $method = isset($r['method']) ? $r['method'] : 'get'; $_ENV['display'] = $display = $r['fmt']; $_ENV['version'] = $version = isset($r['version']) ? $r['version'] : 1; $classname = 'CA_Entry_' . $module; if (!method_exists($classname, $method) && !method_exists($classname, '__call')) { $classname .= '_' . $method; $run = isset($_GET['a']) ? $_GET['a'] : 'run'; if (!method_exists($classname, $run)) { $errno = CYE_PARAM_ERROR; $error = "method is not exists {$classname}:{$method}"; goto error; } } switch ($display) { case 'raw': $req = $b['raw_body']; break; case 'json': $req = json_decode($b['raw_body'], true); if (empty($req)) { $errno = json_last_error(); $error = json_last_error_msg(); goto error; } break; case 'mgp': $req = msgpack_unpack($b['raw_body']); $req = ['errno' => 0, 'data' => $data]; break; default: $errno = -1; $error = 'unkown formant'; break; } $eny = new $classname(); $dt = $eny->get($id, $req, $_ENV); unset($eny); response: switch ($display) { case 'raw': $body = $dt; break; case 'json': $body = json_encode($dt); break; case 'mpg': $body = msgpack_pack($dt); break; default: $body = 'unknown format ' . $display; break; } if (empty($body) || !is_string($body)) { return ['errno' => 0, 'error' => 'error response body.']; } $hd = ['raw_len_head' => 0, 'raw_header' => '']; if (isset($b['raw_len_head'])) { $hd['raw_len_head'] = $b['raw_len_head']; } if (isset($b['raw_header'])) { $hd['raw_header'] = $b['raw_header']; } $inputs = array([CY_TYPE_UINT16, $hd['raw_len_head']], [CY_TYPE_STRING, $hd['raw_header']], [CY_TYPE_UINT16, strlen($body)], [CY_TYPE_STRING, $body]); return ['errno' => $errno, 'error' => $error, 'data' => cy_pack($inputs)]; error: $dt = array('errno' => $errno, 'error' => $error); cy_log(CYE_WARNING, "{$client} " . $error); goto response; }
function master_timer($tw) { if (!is_object($tw) && get_class($tw) !== 'EvTimer') { cy_log(CYE_ERROR, 'wrong type param called in master_timer'); return; } //restart by luohaibin if (cy_i_get('bps_srv_status', CY_TYPE_SYS) == 1) { cy_i_set('bps_srv_status', CY_TYPE_SYS, 0); $this->flag = WKST_SPAWN; $this->worker_start(); $this->worker_clean(); $this->flag = WKST_RUNNING; } //force stop if (cy_i_get('bps_srv_status', CY_TYPE_SYS) == 2) { cy_i_set('bps_srv_status', CY_TYPE_SYS, 0); //master exit $this->flag = WKST_END; //worker force terminate $this->worker_clean(); // TODO need wait. //$this->loop->stop(); } /* Dead lock detect. */ /* $max = isset($_ENV['config']['max_lock_time']) ? $_ENV['config']['max_lock_time'] : 1; $now = time(); foreach($this->workers as $pid => $worker) { if(cy_i_get('bps_srv_lock_'.$pid, CY_TYPE_SYS)) { if($this->status['pid'] != $pid) { $this->status['pid'] = $pid; $this->status['time'] = $now; break; } if($now - $this->status['time'] > $max) { cy_log(CYE_ERROR, 'kill process '.$pid.' who had lock more than '.$max.'s'); cy_i_set('bps_srv_term_'.$pid, CY_TYPE_SYS, 1); } break; } } */ }
function srv_finish() { $error = error_get_last(); if ($error['type'] === E_ERROR) { cy_log(CYE_ERROR, 'cy_srv_finish fatal errors found %s', json_encode($error)); // 防止因为fatal error导致死锁 /* if($this->unlock()) { cy_log(CYE_ERROR, 'cy_srv_finish unlock the process, fatal error happen in process.'); } */ } cy_i_del('bps_srv_term_' . $this->pid, CY_TYPE_SYS); cy_i_del($this->stat_name, CY_TYPE_SYS); }
function query($sql, $options = []) { $timeout = isset($options['timeout']) ? $options['timeout'] : $_ENV['config']['timeout']['mysql_read']; if (!$this->is_avaliable()) { return cy_dt(CYE_DB_CONNECT_ERROR, 'mysql connect is not available.'); } $this->db->query($sql, MYSQLI_ASYNC); $finished = 0; $t1 = microtime(true); while (!$finished) { $links = $errors = $reject = [$this->db]; if (!mysqli_poll($links, $errors, $reject, 0, 100000)) { if (microtime(true) - $t1 < $timeout) { continue; } $this->db->close(); cy_log(CYE_ERROR, 'mysql query timeout, over %f second', $timeout); $dt = cy_dt(CYE_NET_TIMEOUT, 'mysql query timeout'); goto end; } $finished = 1; } if (!($result = $this->db->reap_async_query())) { cy_log(CYE_ERROR, 'mysql query error [%d] [%s]', $this->db->errno, $this->db->error); $dt = cy_dt($this->db->errno, $this->db->error); goto end; } /* For successful SELECT, SHOW, DESCRIBE or EXPLAIN queries mysqli_query() will return a mysqli_result object */ if (is_object($result)) { $rows = $result->fetch_all(MYSQLI_ASSOC); mysqli_free_result($result); $dt = cy_dt(0, $rows); goto end; } /* For other successful queries mysqli_query() will return TRUE. */ $r = ['affected_rows' => $this->db->affected_rows, 'insert_id' => $this->db->insert_id]; $dt = ['errno' => 0, 'data' => $r, 'info' => $this->db->info]; end: $t2 = microtime(true); cy_stat('mysql-query', ($t2 - $t1) * 1000000); return $dt; }
function loop($callback, $nowait = false, $timeout = 0) { if (!$this->runing) { cy_exit(CYE_SYSTEM_ERROR); } try { $this->callback = $callback; $this->channel->basic_qos(null, 1, null); $this->channel->basic_consume($this->queue, '', false, false, false, false, [$this, 'recv']); do { $this->channel->wait(null, $nowait, $timeout); } while (!$nowait); } catch (Exception $e) { cy_log(CYE_ERROR, $e->getMessage()); } }
function connect($config) { if (empty($config)) { $mysql_conf = $_ENV['config']['db']; } else { $mysql_conf = $config; } if (empty($mysql_conf)) { $mysql_conf = [['host' => '127.0.0.1', 'port' => '3306', 'user' => '', 'password' => '', 'database' => '']]; } $cfg_count = count($mysql_conf); $i = array_rand($mysql_conf, 1); $re = 0; do { $i = ($i + 1) % $cfg_count; $config = $mysql_conf[$i]; $server = $config['host'] . ':' . $config['port']; } while (0); //while(!cy_ctl_check($server, $_SERVER['REQUEST_TIME']) && $re++ < $cfg_count); if (empty($config)) { cy_log(CYE_ERROR, 'Mysqlc::connect DB config is not found.'); return NULL; } $t1 = microtime(true); $conn = new CY_Mysqli(); $to = $_ENV['config']['timeout']; $conn->options(MYSQLI_OPT_CONNECT_TIMEOUT, $to['mysql_connect']); $conn->options(MYSQLI_OPT_READ_TIMEOUT, $to['mysql_read']); $conn->options(MYSQLI_OPT_WRITE_TIMEOUT, 1); $ret = $conn->real_connect($config['host'], $config['user'], $config['password'], $config['database'], $config['port']); if (!$ret) { //cy_log(CYE_WARNING, "connect to [%s] at port [%s] failed, %s", $config['host'], $config['port'], $conn->connect_error); //cy_stat('mysql-connect', (microtime(true) - $t1)*1000000, ['errno' => $conn->connect_errno]); //cy_ctl_fail($server, $_SERVER['REQUEST_TIME']); return NULL; } $conn->setcfg($config); $conn->set_charset("utf8"); $conn->query("set names utf8,character_set_client=binary"); //cy_ctl_succ($server, $_SERVER['REQUEST_TIME']); cy_stat('mysql-connect', (microtime(true) - $t1) * 1000000); return $conn; }
function __call($method, $args) { $data = []; $call = ['mGet' => 'find', 'save' => 'save', 'mInsert' => 'batchInsert', 'delete' => 'remove', 'update' => 'update']; $getid = ['mGet' => false, 'save' => 'save', 'mInsert' => true, 'delete' => false, 'update' => true]; if (empty($call[$method])) { return cy_dt(-1, 'unkown method.'); } $t1 = microtime(true); $table = array_shift($args); $dbname = $this->c['database']; try { if (!self::$mongo) { self::$mongo = $this->connect(); } $db = self::$mongo->{$dbname}; $c10n = $table == 'file' ? $db->getGridFS() : $db->{$table}; $back = call_user_func_array([$c10n, $call[$method]], $args); if (is_object($back)) { $back = iterator_to_array($back); } else { if ($getid[$method] && $back) { $list = array(); foreach ($args as $k => $v) { $list[$k] = (string) $v['_id']; } $back = $list; } } $data = cy_dt(0, $back); //self::$mongo->close(); } catch (MongoCursorException $e) { $error = substr($e->getMessage(), 0, 512); cy_log(CYE_ERROR, "mongo-{$method} " . $error); $data = cy_dt(CYE_SYSTEM_ERROR, $error); } catch (MongoCursorTimeoutException $e) { $error = substr($e->getMessage(), 0, 512); cy_log(CYE_ERROR, "mongo-{$method} " . $error); cy_log(CYE_ERROR, "mongo-{$method} close=%d, reconnect=%d", self::$mongo->close(), self::$mongo->connect); $data = cy_dt(CYE_SYSTEM_ERROR, $error); } catch (MongoConnectionException $e) { $error = substr($e->getMessage(), 0, 512); cy_log(CYE_ERROR, "mongo-{$method} " . $error); $data = cy_dt(CYE_SYSTEM_ERROR, $error); } catch (Exception $e) { $error = substr($e->getMessage(), 0, 512); cy_log(CYE_ERROR, "mongo-{$method} " . $error); $data = cy_dt(CYE_SYSTEM_ERROR, $error); } // end process. $cost = (microtime(true) - $t1) * 1000000; cy_stat('mongo-' . $method, $cost); return $data; }
/** * NOTICE: * tag space shoud be remove before invoke this function. * eg: </ a > shoud be replace to </a> * * @author: * Jianyu<*****@*****.**> * * Example: * * $html: * * */ function cy_split_by_tag1($html, $tags = []) { $length = strlen($html); /* 防止出Warings,又减少计算量的track做法 */ for ($i = 0; $i < $length; $i++) { begin: /* NOTICE: $i just at '|' */ /** * Find out: * xxxx|<foo> * xxxx|<foo ...> * or xxxx|</foo> * * but ignore: * xxxx|<html> end of xxxx will be ignored. */ $p = strpos($html, '<', $i); /*** * Last html tag * * may be: * </html>|\r\n * */ if ($p === false) { /* Skip tag will make non empty $text. */ if (!empty($text)) { (yield $i => trim($text)); } break; } /* xxxx|<foo> or xxxx|</foo>, restore 'xxxx' as new line. */ if (!empty($text)) { /** * Right now $text may be the first part of: * <foo .... />| or * <foo...>..</foo>| or * <foo xxxxxxx>|....</foo> * </foo>| */ /* Skip tag will make non empty $text. */ $text .= "\n"; $text .= trim(substr($html, $i, $p - $i)); (yield $i => trim($text)); $text = ''; } else { (yield $i => trim(substr($html, $i, $p - $i))); } $i = strpos($html, '>', $p); if (!$i) { cy_log(CYE_WARNING, 'invalid html content "<" without ">" at the end.'); break; } $w = $html[$p + 1] !== '/' ? 1 : 2; /** * Then: * $i <foo|>xxxx or </foo|>xxxx or <foo ...|> or </html|> * $p |<foo>xxxx or |</foo>xxxx or |<foo ...> or |</html> */ /** * Get next html tag name */ $y = $p; while (cy_is_w($html[++$y])) { } /** * Right now * $i: <foo|>xxxx or </foo|>xxxx or <foo ...|> or </html|> * $p: |<foo>xxxx or |</foo>xxxx or <foo ...|> or |</html> * $y: <foo|>xxxx or </foo|>xxxx or <foo| ...> or </html|> * $p + $w: * <|foo>xxxx or </|foo>xxxx or <|foo ...> or </|html> * * so $t == 'foo' */ $t = strtolower(substr($html, $p + $w, $y - $p - $w)); /* if need skip */ if (!empty($t) && in_array($t, $tags)) { /** * <p> is a very speical tag * most of web editors support <p>, contents in <p> should not be separated. */ if ($t === 'p') { if ($w === 2) { cy_log(CYE_WARNING, "found </p> without <p>, skip it."); $i = $p + 4; goto begin; } $y = $k = $p; /* $y, $k, $p: * |<p>...</p> or * |<p ...>...</p> or * |<p> .. <p>.. </p> </p> or * * Invalid: * |<p> ..<p> </p> not enongh '</p>' */ do { /* Invalid <p> tag, just skip it. */ if (($x = stripos($html, '</p>', $k)) === false) { cy_log(CYE_WARNING, "content at {$p} found unclosed <p> tag"); $i = $p + 3; /* Right new $i at <p>| .. <p> .. </p> */ goto begin; } $k = $x + 4; /** * $x: <p> .. <p>.. |</p> </p> $ $k: <p> .. <p>.. </p>| </p> * $p: |<p> .. <p>.. </p> </p> */ $z = substr($html, $y, $k - $y); /* Make sure $z have't <p...> or <p> */ do { $j = stripos($z, '<p', 2); } while (cy_is_w($z[$j + 2]) && ($z = substr($z, $j + 2))); /** * so, $j = position of <p..> | <p> or false. */ $y += (int) $j; } while ($j); /** * finally: * * $p: |<p> .. <p>.. </p> </p> * $k: <p> .. <p>.. </p> </p>| */ } else { /* * $p: |<foo...> or |</foo> * $k: <foo...>| or </foo>| */ $k = strpos($html, '>', $p) + 1; } /* save the skipped html into $text */ $text = substr($html, $p, $k - $p); $i = $k - 1; } /* skip tags end . */ } }
function dispatch($request_uri, $options) { /* parse request uri start * ----------------------------------- */ $p = strpos($request_uri, '?'); $request_uri = $p !== false ? substr($request_uri, 0, $p) : $request_uri; /* security request uri filter. */ if (preg_match('/(\\.\\.|\\"|\'|<|>)/', $request_uri)) { return array('errno' => 403, 'data' => "permission denied."); } /* get display format. */ if (($p = strrpos($request_uri, '.')) !== false) { $tail = substr($request_uri, $p + 1); if (preg_match('/^[a-zA-Z0-9]+$/', $tail)) { $display = $tail; //'json' $request_uri = substr($request_uri, 0, $p); } } /* get version, module, id, method. */ $requests = array_pad(explode('/', $request_uri, 5), 5, NULL); list(, $module, $id, $method) = $requests; /* default format: json */ empty($display) && ($display = 'json'); empty($method) && ($method = 'get'); if (isset($_GET['id'])) { $id = $_GET['id']; } $_ENV['module'] = $module; $_ENV['id'] = $id; $_ENV['method'] = $method; $_ENV['display'] = $display; //$_ENV['version']= $version; /*------------------------------------- * parse request uri end */ if (empty($module)) { $dt = array('errno' => CYE_PARAM_ERROR, 'code' => 404, 'data' => 'Not found.'); goto end; } if ($module == 'static') { $file = CY_HOME . '/app' . $request_uri . '.' . $display; if (is_file($file)) { $content = file_get_contents($file); return ['errno' => 0, 'code' => 200, 'data' => $content]; } } $classname = 'CA_Entry_' . $module; if (!method_exists($classname, $method) && !method_exists($classname, '__call')) { $classname .= '_' . $method; $run = isset($_GET['a']) ? $_GET['a'] : 'run'; if (!method_exists($classname, $run)) { $errno = CYE_PARAM_ERROR; $error = "method is not exists {$classname}:{$method}"; $dt = array('errno' => $errno, 'code' => 404, 'data' => 'unkown request.', 'error' => $error); goto end; } $eny = new $classname(); $dt = $eny->{$method}($id, $_REQUEST, $_ENV); } else { $eny = new $classname(); $dt = $eny->{$method}($id, $_REQUEST, $_ENV); } unset($eny); if ($dt['errno'] !== 0) { cy_log(CYE_ERROR, json_encode($dt)); if ($dt['errno'] != CYE_PARAM_ERROR) { $dt['code'] = 500; } else { $dt['code'] = 200; } if (empty($dt['error'])) { $dt['data'] = 'Internal error.'; } else { $dt['data'] = $dt['error']; } } else { $dt['code'] = 200; } end: if ($display === 'html' || $display === 'php') { if ($dt['errno'] == 0) { $files = array(); $files[] = CY_HOME . '/app/html/' . $module . '/' . $method . '.' . $display; $files[] = CY_HOME . '/app/html/' . $module . '.' . $display; $files[] = CY_HOME . '/app/html/default.' . $display; foreach ($files as $i => $file) { if (is_file($file)) { break; } if ($i === 1 && $display === 'html') { $_ENV['display'] = $display = 'php'; goto end; } } } else { $file = CY_HOME . '/app/html/error.' . $display; } } else { $file = NULL; } $t = new CY_Util_Output(); $t->assign(['errno' => $dt['errno'], 'data' => $dt['data']]); $data = $t->get($file); return ['errno' => 0, 'code' => $dt['code'], 'data' => $data]; }
function mSet($data, $options = []) { $chunk_size = isset($options['chunk_size']) ? $options['chunk_size'] : 50; $chunk_data = array_chunk($data, $chunk_size); $update = isset($options['update']) ? $options['update'] : false; $table = isset($options['prefix']) ? $options['prefix'] . '_' . $this->table : $this->table; $i = 0; foreach ($chunk_data as $chunk) { $r = ['data' => $chunk]; $c = new CY_Driver_DB_Default($table, $r, ['method' => 'insert', 'update' => $update]); $this->db->add($i++, $c); } $dt = $this->db->mGet(); if ($dt['errno'] !== 0) { return $dt; } $insert_id = PHP_INT_MAX; $affected_rows = 0; foreach ($dt['data'] as $i => $dt_sub) { if ($dt_sub['errno'] !== 0) { cy_log(CYE_WARNING, 'MySQL::mSet part failed.'); continue; } $v = $dt_sub['data']; if ($v['insert_id'] === 0 || $v['affected_rows'] === 0) { cy_log(CYE_DEBUG, 'MySQL::mSet insert but no affect, maybe exists'); continue; } $insert_id > $v['insert_id'] && ($insert_id = $v['insert_id']); $affected_rows += $v['affected_rows']; } $insert_id === PHP_INT_MAX && ($insert_id = 0); return cy_dt(0, ['insert_id' => $insert_id, 'affected_rows' => $affected_rows]); }
function srv_finish() { $error = error_get_last(); if ($error['type'] === E_ERROR) { cy_log(CYE_ERROR, 'cy_srv_finish fatal errors found %s', json_encode($error)); } cy_i_del('bps_srv_term_' . $this->pid, CY_TYPE_SYS); }
/** * cy_stat_flush * * 如果$_ENV['stat'], 太大,可以会造成memory leak, 有时间需要手动刷一下。 */ function cy_stat_flush() { $endtime = microtime(true); $elapsed = (int) (($endtime - $_ENV['stat_time']) * 1000000); $post_data = empty($_POST) ? '' : 'input=' . json_encode(array_keys($_POST)) . ' '; empty($_ENV['stat']) && ($_ENV['stat'] = []); empty($_ENV['stat_flush_times']) && ($_ENV['stat_flush_times'] = 0); cy_log(CYE_ACCESS, 'memory:%d %s elapsed={total:%d,detail:%s}', memory_get_usage(), $post_data, $elapsed, json_encode($_ENV['stat'])); $_ENV['stat'] = array(); $_ENV['stat_count'] = 0; $_ENV['stat_time'] = $endtime; $_ENV['stat_flush_times'] += 1; }