void ArdbServer::TouchIdleConn(Channel* ch) { static ThreadLocal<IdleConnManager> kLocalIdleConns; uint64 now = get_current_epoch_millis(); IdleConn conn; conn.conn_id = ch->GetID(); conn.ts = now; IdleConnManager& m = kLocalIdleConns.GetValue(); if (m.timer_id == -1) { m.serv = &(ch->GetService()); m.maxIdleTime = m_cfg.timeout * 1000; m.lru.SetMaxCacheSize(m_cfg.max_clients); m.timer_id = ch->GetService().GetTimer().Schedule(&m, 1, 5, SECONDS); } IdleConn tmp; m.lru.Insert(conn.conn_id, conn, tmp); }
int LUAInterpreter::CallArdb(lua_State *lua, bool raise_error) { int j, argc = lua_gettop(lua); ArgumentArray cmdargs; /* Require at least one argument */ if (argc == 0) { luaPushError(lua, "Please specify at least one argument for redis.call()"); return 1; } /* Build the arguments vector */ for (j = 0; j < argc; j++) { if (!lua_isstring(lua, j + 1)) break; std::string arg; arg.append(lua_tostring(lua, j + 1), lua_strlen(lua, j + 1)); cmdargs.push_back(arg); } /* Check if one of the arguments passed by the Lua script * is not a string or an integer (lua_isstring() return true for * integers as well). */ if (j != argc) { luaPushError(lua, "Lua redis() command arguments must be strings or integers"); return 1; } /* Setup our fake client for command execution */ RedisCommandFrame cmd(cmdargs); Ardb::RedisCommandHandlerSetting* setting = g_db->FindRedisCommandHandlerSetting(cmd); /* Command lookup */ if (NULL == setting) { luaPushError(lua, "Unknown Redis command called from Lua script"); return -1; } /* There are commands that are not allowed inside scripts. */ if (!setting->IsAllowedInScript()) { luaPushError(lua, "This Redis command is not allowed from scripts"); return -1; } LuaExecContext* ctx = g_lua_exec_ctx.GetValue(); /* Write commands are forbidden against read-only slaves, or if a * command marked as non-deterministic was already called in the context * of this script. */ if (setting->IsWriteCommand()) { if (!g_db->GetConf().master_host.empty() && g_db->GetConf().slave_readonly && !g_db->IsLoadingData() && !(ctx->caller->flags.slave)) { luaPushError(lua, "-READONLY You can't write against a read only slave."); return -1; } } Context& lua_ctx = ctx->exec; RedisReply& reply = lua_ctx.GetReply(); reply.Clear(); lua_ctx.ClearFlags(); lua_ctx.flags.lua = 1; g_db->DoCall(lua_ctx, *setting, cmd); if (raise_error && reply.type != REDIS_REPLY_ERROR) { raise_error = 0; } redisProtocolToLuaType(lua, reply); if (raise_error) { /* If we are here we should have an error in the stack, in the * form of a table with an "err" field. Extract the string to * return the plain error. */ lua_pushstring(lua, "err"); lua_gettable(lua, -2); return lua_error(lua); } return 1; }
return -1; } if (!lua_isboolean(lua, 1)) { luaPushError(lua, "Lua assert2() command argument[0] must be boolean"); return -1; } int b = lua_toboolean(lua, 1); if (b) { fprintf(stdout, "\e[1;32m%-6s\e[m %s:%d\n", "[PASS]", g_lua_file, lua_line); } else { LuaExecContext* ctx = g_lua_exec_ctx.GetValue(); ctx->lua_abort = true; const char* actual = NULL; std::string tablestr; int obj_type = lua_type(lua, 2); if (lua_istable(lua, 2)) { print_lua_table(lua, 2, tablestr); actual = tablestr.c_str(); } else if (lua_isboolean(lua, 2)) { actual = lua_toboolean(lua, 2) ? "true" : "false"; } else {
ArdbConnContext* GetCurrentContext() { return m_ctx_local.GetValue(); }