bool ServerIOCallback::read_callback(char* data, int len) { const char* myname = "read_callback"; if (data == NULL || *data == 0 || len <= 0) { logger_warn("invalid data: %s, len: %d", data ? data : "null", len); return false; } // 处理服务端发来的命令 acl::url_coder coder; coder.decode(data); logger_debug(DEBUG_SVR, 1, "client: %s", data); const char* ptr = coder.get("count"); if (ptr == NULL) { logger_warn("%s(%d), %s: no count", __FILE__, __LINE__, myname); return true; } unsigned int nconns = (unsigned int) atoi(ptr); conn_->set_nconns(nconns); // 尝试将服务端连接对象添加进服务端管理对象中 ServerManager::get_instance().set(conn_); return true; }
// VmVyc2lvbjogMQ0KWGZyQ291bnQ6IDENCg== // decode result:Version: 1 // XfrCount: 1 void CMsnDSClient::parse_xfr_ver(const char* data) { acl::string buf; buf.base64_decode(data, strlen(data)); if (buf.empty()) return; const std::list<acl::string>& args = buf.split("\r\n"); std::list<acl::string>::const_iterator cit = args.begin(); for (; cit != args.end(); cit++) { acl::string line = *cit; char* name = line.c_str(); char* value = strchr(name, ':'); if (value == NULL || *(value + 1) == 0) { logger_warn("invalid line(%s)", name); continue; } *value++ = 0; while (*value == ' ' || *value == '\t') value++; if (*value == 0) { logger_warn("invalid line(%s: )", name); continue; } if (strcasecmp(name, "Version") == 0) xfr_ver_ = atoi(value); else if (strcasecmp(name, "XfrCount") == 0) xfr_cnt_ = atoi(value); } }
const string& query::to_string() { if (params_.empty()) return sql_; if (sql_buf_ == NULL) sql_buf_ = NEW string(sql_.length() + 32); else sql_buf_->clear(); #define SKIP_WHILE(cond, ptr) { while(*ptr && (cond)) ptr++; } char last_ch; char* src = sql_.c_str(), *ptr, *key; while (*src != 0) { ptr = strchr(src, ':'); if (ptr == NULL) { sql_buf_->append(src); break; } else if (*++ptr == 0) { sql_buf_->append(src); logger_warn("the last char is ':'"); break; } sql_buf_->append(src, ptr - src - 1); key = ptr; SKIP_WHILE(*ptr != ',' && *ptr != ';' && *ptr != ' ' && *ptr != '\t' && *ptr != '(' && *ptr != ')' && *ptr != '\r' && *ptr != '\n', ptr); if (ptr - key == 1) { logger_warn("only found: ':%c'", *ptr); sql_buf_->append(key, ptr - key + 1); src = ptr + 2; continue; } last_ch = *ptr; *ptr = 0; (void) append_key(*sql_buf_, key); *ptr = last_ch; if (last_ch == '\0') break; src = ptr; } return *sql_buf_; }
bool http_servlet::doPost(request_t& req, response_t& res) { // 如果需要 http session 控制,请打开下面注释,且需要保证 // 在 master_service.cpp 的函数 thread_on_read 中设置的 // memcached 服务正常工作 /* const char* sid = req.getSession().getAttribute("sid"); if (*sid == 0) req.getSession().setAttribute("sid", "xxxxxx"); sid = req.getSession().getAttribute("sid"); */ // 如果需要取得浏览器 cookie 请打开下面注释 /* $<GET_COOKIES> */ const char* path = req.getPathInfo(); if (path == NULL || *path == 0) { logger_error("path null"); return false; } // 根据 uri path 查找对应的处理句柄,从而实现 HTTP 路由功能 std::map<std::string, handler_t>::iterator it = handlers_.find(path); if (it == handlers_.end()) { logger_warn("not support, path=%s", path); return false; } return (this->*it->second)(req, res); }
acl_int64 aio_timer_callback::del_task(unsigned int id) { bool ok = false; std::list<aio_timer_task*>::iterator it = tasks_.begin(); for (; it != tasks_.end(); ++it) { if ((*it)->id == id) { delete (*it); tasks_.erase(it); length_--; ok = true; break; } } if (!ok) logger_warn("timer id: %u not found", id); if (tasks_.empty()) return TIMER_EMPTY; set_time(); acl_int64 delay = tasks_.front()->when - present_; return delay < 0 ? 0 : delay; }
redis_result* redis_client::get_redis_object(dbuf_pool* pool) { char ch; if (conn_.read(ch) == false) { logger_warn("read char error: %s, server: %s, fd: %u", last_serror(), addr_, (unsigned) conn_.sock_handle()); return NULL; } switch (ch) { case '-': // ERROR return get_redis_error(pool); case '+': // STATUS return get_redis_status(pool); case ':': // INTEGER return get_redis_integer(pool); case '$': // STRING return get_redis_string(pool); case '*': // ARRAY return get_redis_array(pool); default: // INVALID logger_error("invalid first char: %c, %d", ch, ch); return NULL; } }
connect_pool* connect_manager::peek() { connect_pool* pool; size_t service_size, n; lock_.lock(); service_size = pools_.size(); if (service_size == 0) { lock_.unlock(); logger_warn("pools's size is 0!"); return NULL; } // 遍历所有的连接池,找出一个可用的连接池 for(size_t i = 0; i < service_size; i++) { n = service_idx_ % service_size; service_idx_++; pool = pools_[n]; if (pool->aliving()) { lock_.unlock(); return pool; } } lock_.unlock(); logger_error("all pool(size=%d) is dead!", (int) service_size); return NULL; }
bool polarssl_io::on_close(bool alive) { #ifdef HAS_POLARSSL if (ssl_ == NULL) { logger_error("ssl_ null"); return false; } if (stream_ == NULL) { logger_error("stream_ null"); return false; } if (!alive) return false; int ret; while((ret = ssl_close_notify((ssl_context*) ssl_ )) < 0) { if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE ) { logger_warn("ssl_close_notify error: -0x%04x", ret); return false; } } #else (void) alive; #endif return true; }
connect_pool* connect_manager::peek(const char* key, bool exclusive /* = true */) { if (key == NULL || *key == 0) return peek(); size_t service_size; connect_pool* pool; unsigned n = acl_hash_crc32(key, strlen(key)); if (exclusive) lock_.lock(); service_size = pools_.size(); if (service_size == 0) { if (exclusive) lock_.unlock(); logger_warn("pools's size is 0!"); return NULL; } pool = pools_[n % service_size]; if (exclusive) lock_.unlock(); return pool; }
void redis_commands::add_cmdline(acl::string& line, size_t i) { std::vector<acl::string>& tokens = line.split2(" \t|:,;"); if (tokens.size() < 3) { logger_warn("skip line(%d): %s", (int) i, line.c_str()); return; } acl::string cmd(tokens[0]); cmd.upper(); if (cmd == "ALL") { all_cmds_perm_ = tokens[2]; all_cmds_perm_.lower(); if (all_cmds_perm_ == "warn" || all_cmds_perm_ == "no") return; return; } REDIS_CMD redis_cmd; redis_cmd.cmd = cmd; redis_cmd.broadcast = tokens[1].equal("yes", false) ? true : false; redis_cmd.perm = tokens[2]; redis_cmd.perm.lower(); if (redis_cmd.perm != "yes" && redis_cmd.perm != "warn") redis_cmd.perm = "no"; redis_cmds_[cmd] = redis_cmd; }
acl_int64 event_timer::del_task(unsigned int id) { bool ok = false; std::list<event_task*>::iterator it = tasks_.begin(); for (; it != tasks_.end(); ++it) { if ((*it)->id == id) { delete (*it); tasks_.erase(it); length_--; ok = true; break; } } if (!ok) logger_warn("timer id: %u not found", id); if (tasks_.empty()) return TIMER_EMPTY; set_time(); event_task* first = tasks_.front(); acl_int64 delay = first->when - present_; if (delay < 0) return 0; else if (delay > first->delay) /* xxx */ return first->delay; else return delay; }
void connect_manager::set_pools_status(const char* addr, bool alive) { std::vector<connect_pool*>::iterator it; connect_pool* pool; const char* ptr; if (addr == NULL || *addr == 0) { logger_warn("addr null"); return; } lock(); it = pools_.begin(); for (; it != pools_.end(); ++it) { pool = *it; ptr = pool->get_addr(); if (ptr && strcasecmp(ptr, addr) == 0) { pool->set_alive(alive); break; } } unlock(); }
// 根据输入的目标地址进行重定向:打开与该地址的连接,如果连接失败,则随机 // 选取一个服务器地址进行连接 redis_client* redis_command::redirect(redis_client_cluster* cluster, const char* addr) { redis_client_pool* conns; // 如果服务器地址不存在,则根据服务器地址动态创建连接池对象 if ((conns = (redis_client_pool*) cluster->get(addr)) == NULL) conns = (redis_client_pool*) &cluster->set(addr, max_conns_); if (conns == NULL) return NULL; redis_client* conn; int i = 0; while (i++ < 5) { conn = (redis_client*) conns->peek(); if (conn != NULL) return conn; conns->set_alive(false); conns = (redis_client_pool*) cluster->peek(); if (conns == NULL) { logger_error("no connections availabble, " "i: %d, addr: %s", i, addr); return NULL; } } logger_warn("too many retry: %d, addr: %s", i, addr); return NULL; }
queue_file* queue_manager::open_file(const char* filePath, bool no_cache /* = true */) { string home, queueName, queueSub, partName, extName; if (queue_manager::parse_filePath(filePath, &home, &queueName, &queueSub, &partName, &extName) == false) { logger_error("filePath(%s) invalid", filePath); return NULL; } queue_file* fp; // 如果该文件存在于内存中则直接返回之 fp = cache_find(partName); if (fp != NULL) { if (no_cache) { logger_warn("file: %s locked", filePath); return NULL; } return fp; } // 从磁盘打开已经存在的队列文件 fp = NEW queue_file; if (fp->open(home.c_str(), queueName.c_str(), queueSub.c_str(), partName.c_str(), extName.c_str()) == false) { delete fp; return NULL; } cache_add(fp); return fp; }
void db_pgsql::load(void) { #ifdef HAS_PGSQL_DLL acl_pthread_once(&__pgsql_once, __pgsql_dll_load); #else logger_warn("link pgsql library in static way!"); #endif }
bool istream::gets(string& s, bool nonl /* = true */, size_t max /* = 0 */) { char buf[8192]; size_t size; s.clear(); if (max == 0) { while (!eof()) { size = sizeof(buf); if (gets(buf, &size, nonl) == true) { if (size > 0) s.append(buf, size); return true; } if (size == 0) break; printf(">>>size: %d\r\n", (int) size); s.append(buf, size); } return false; } size_t saved_max = max; while (!eof()) { size = sizeof(buf) > max ? max : sizeof(buf); if (gets(buf, &size, nonl) == true) { if (size > 0) s.append(buf, size); return true; } if (size == 0) break; s.append(buf, size); max -= size; if (max == 0) { logger_warn("reached the max limit: %d", (int) saved_max); return true; } } return false; }
int hsclient::get_id() const { if (tbl_curr_ == NULL) { logger_warn("tbl not open!"); return (-1); } return (tbl_curr_->id_); }
bool queue_manager::rename_extname(queue_file* fp, const char* extName) { if (cache_check(fp) == false) { logger_warn("file(%s)'s key(%s) not exist", fp->get_filePath(), fp->key()); return false; } return fp->move_file(fp->get_queueName(), extName); }
// 设置联系人列表中的成员的在线状态 Member* CMsnContactManager::SetUserStatus(const char* passportName, const char* status, const char* displayName) { acl_assert(passportName && status && displayName); std::map<acl::string, Member*>::iterator it = users_.find(passportName); if (it == users_.end()) return (NULL); Member* member = it->second; if (strcasecmp(status, "NLN") == 0) member->online_ = member_s_online; else if (strcasecmp(status, "IDL") == 0) member->online_ = member_s_idle; else if (strcasecmp(status, "BSY") == 0) member->online_ = member_s_busy; else if (strcasecmp(status, "AWY")) member->online_ = member_s_away; else logger_warn("unkown status: %s", status); acl::string buf; // 字符集转换成 GB18030 bool ret = conv_.convert("UTF-8", "GB18030", displayName, strlen(displayName), &buf); if (ret == false) { logger_warn("convert from utf-8 to GB18030 error"); return (member); } if (!STRING_IS_EMPTY(member->DisplayName)) acl_myfree(member->DisplayName); member->DisplayName = acl_mystrdup(buf.c_str()); return (member); }
void status_manager::del_status(const char* key) { acl_assert(key && *key); std::map<acl::string, server_status*>::iterator it = servers_status_.find(key); if (it == servers_status_.end()) { logger_warn("key: %s not found", key); return; } delete it->second; servers_status_.erase(it); }
void ipc_client::trigger(int nMsg, void* data, int dlen) { std::list<int>::iterator it = messages_.begin(); // 该消息是否已经存在于已经注册的消息集合中 for (; it != messages_.end(); ++it) { if (*it == nMsg) { on_message(nMsg, data, dlen); return; } } logger_warn("unknown msg: %d", nMsg); }
bool query::append_key(string& buf, char* key) { acl_lowercase(key); std::map<string, query_param*>::iterator it = params_.find(key); if (it == params_.end()) { logger_warn("unknown key: %s", key); buf.append(key); return false; } char fmt[256]; query_param* param = it->second; switch (param->type) { case DB_PARAM_CHAR: buf.format_append("'%c'", param->v.c); break; case DB_PARAM_SHORT: buf.format_append("%d", param->v.s); break; case DB_PARAM_INT32: buf.format_append("%d", param->v.n); break; case DB_PARAM_INT64: buf.format_append("%lld", param->v.l); break; case DB_PARAM_STR: buf.format_append("'%s'", escape(param->v.S, param->dlen, buf_).c_str()); break; case DB_PARAM_FLOAT: safe_snprintf(fmt, sizeof(fmt), "%%.%df", param->precision); buf.format_append(fmt, param->v.f); break; case DB_PARAM_DOUBLE: safe_snprintf(fmt, sizeof(fmt), "%%.%df", param->precision); buf.format_append(fmt, param->v.d); break; default: logger_error("unknown type: %d", param->type); break; } return true; }
bool connect_manager::start_monitor(connect_monitor* monitor) { if (monitor_ != NULL) { logger_warn("one connect_monitor running!"); return false; } monitor_ = monitor; // 设置检测线程为非分离模式,以便于主线程可以等待检测线程退出 monitor_->set_detachable(false); // 启动检测线程 monitor_->start(); return true; }
bool master_service::thread_on_read(acl::socket_stream* conn) { acl::string buf; if (conn->gets(buf) == false) { logger_warn("gets error from %s, fd %d", conn->get_peer(), conn->sock_handle()); return false; } else if(conn->format("%s\r\n", buf.c_str()) == -1) return false; else if (buf == "quit") return false; else return true; }
bool req_callback::read_callback(char* data, int len) { if (res_ == NULL) { logger_warn("server peer disconnected!"); return false; } // 取得服务端连接,并将数据写入 acl::aio_socket_stream& peer = res_->get_conn(); peer.write(data, len); // 将数据写入本地请求文件 if (req_fp_) req_fp_->write(data, len); return true; }
bool master_service::on_accept(acl::aio_socket_stream* client) { if (0) logger("connect from %s, fd %d", client->get_peer(true), client->sock_handle()); acl_non_blocking(client->sock_handle(), ACL_BLOCKING); IConnection* conn; // 根据客户端连接服务端口号的不同来区分不同的服务应用协议 const char* local = client->get_local(true); if (acl_strrncasecmp(local, var_cfg_backend_service, strlen(var_cfg_backend_service)) == 0) { // 创建服务对象处理来自于后端服务模块的请求 conn = new ServerConnection(client); } else if (acl_strrncasecmp(local, var_cfg_status_service, strlen(var_cfg_status_service)) == 0) { const char* ip = client->get_peer(); if (ip == NULL || *ip == 0) { logger_error("can't get peer ip"); return false; } if (allow_list::get_instance().allow_manager(ip) == false) { logger_warn("deny manager ip: %s", ip); return false; } // 创建服务对象处理状态汇报的请求 conn = new StatusConnection(client); } else // 创建对象处理来自于前端客户端模块的请求 conn = new ClientConnection(client, var_cfg_conn_expired); conn->run(); return true; }
connect_pool* connect_manager::peek() { connect_pool* pool; size_t service_size, n; lock_.lock(); service_size = pools_.size(); if (service_size == 0) { lock_.unlock(); logger_warn("pools's size is 0!"); return NULL; } n = service_idx_ % service_size; service_idx_++; lock_.unlock(); pool = pools_[n]; return pool; }
void redis_monitor::status(void) { acl::redis_client client(addr_, conn_timeout_, rw_timeout_); acl::redis redis(&client); std::vector<acl::redis_node*> nodes; redis_util::get_nodes(redis, prefer_master_, nodes); if (nodes.empty()) { logger_error("no redis nodes available"); return; } std::vector<acl::redis_client*> conns; for (std::vector<acl::redis_node*>::const_iterator cit = nodes.begin(); cit != nodes.end(); ++cit) { const char* addr = (*cit)->get_addr(); if (addr == NULL || *addr == 0) { logger_warn("addr NULL, skip it"); continue; } acl::redis_client* conn = new acl::redis_client( addr, conn_timeout_, rw_timeout_); conns.push_back(conn); } while (true) { show_status(conns); sleep(1); } for (std::vector<acl::redis_client*>::iterator it = conns.begin(); it != conns.end(); ++it) { delete *it; } }
void ManagerTimer::timer_callback(unsigned int) { ClientConnection* client; // 从客户端管理对象弹出所有延迟待处理的客户端连接对象 // 并传递给服务端,如果传递失败,则再次置入客户端管理 // 对象,由下次定时器再次尝试处理 logger("total client: %d, total server: %d", (int) ClientManager::get_instance().length(), (int) ServerManager::get_instance().length()); while (true) { client = ClientManager::get_instance().pop(); if (client == NULL) break; if (transfer(client) == true) { ClientManager::get_instance().del(client); delete client; continue; } // 如果在规定的时间内依然没有服务端准备接收连接, // 则直接删除该对象 if (client->expired()) { logger_error("no server side, client(%s) expired!", client->get_peer()); delete client; } else { logger_warn("set client(%s) into queue", client->get_peer()); ClientManager::get_instance().set(client); } break; } }
void check_timer::remove_client(const char* addr, check_client* checker) { // 从当前检查服务器地址列表中删除当前的检测地址 std::map<string, int>::iterator it1 = addrs_.find(addr); if (it1 != addrs_.end()) addrs_.erase(it1); else logger_warn("not found addr: %s", addr); // 从检测连接集群中删除本连接对象 for (std::vector<check_client*>::iterator it2 = checkers_.begin(); it2 != checkers_.end(); ++it2) { if ((*it2) == checker) { checkers_.erase(it2); break; } } }