Powered by nginx

Video

Redisconf 2016 talk notes

slides (pdf)

hsss

Easily embed Lua Scrips in C.
Install with gem install hsss. Full documentation at https://github.com/slact/hsss

Redis + hsss

https://github.com/slact/redis

Lua scripts and Redis in Nchan

'SCRIPT LOAD' callback for redisAsyncCommand to handle error checking (from Nchan)

static void redisLoadScriptCallback(redisAsyncContext *c, void *r, void *privdata) {
  redis_lua_script_t  *script = privdata;
  redisReply *reply = r;
  if (reply == NULL) return;
  switch(reply->type) {
    case REDIS_REPLY_ERROR:
      //output script loading error along with the script name
      ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "nchan: Failed loading redis lua script %s :%s", script->name, reply->str);
      break;
    case REDIS_REPLY_STRING:
      //no error, but make sure the hash is correct, just in case
      if(ngx_strncmp(reply->str, script->hash, REDIS_LUA_HASH_LENGTH)!=0) {
        ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "nchan Redis lua script %s has unexpected hash %s (expected %s)", script->name, reply->str, script->hash);
      }
      break;
  }
}
static void redisInitScripts(redisAsyncContext *c){
  redis_lua_script_t  *script;
  REDIS_LUA_SCRIPTS_EACH(script) { //use the hsss script iterator macro
    redisAsyncCommand(c, &redisLoadScriptCallback, script, "SCRIPT LOAD %s", script->script);
  }
}

redisAsyncCommand callback error handler (from Nchan)

static void redisCheckErrorCallback(redisAsyncContext *c, void *r, void *privdata) {
  static const ngx_str_t script_error_start= ngx_string("ERR Error running script (call to f_");
  redisReply *reply = (redisReply *)r;
  if(reply != NULL && reply->type == REDIS_REPLY_ERROR) {
    if(ngx_strncmp(reply->str, script_error_start.data, script_error_start.len) == 0 && (unsigned ) reply->len > script_error_start.len + REDIS_LUA_HASH_LENGTH) {
      char *hash = &reply->str[script_error_start.len];
      redis_lua_script_t  *script;
      REDIS_LUA_SCRIPTS_EACH(script) {
        if (ngx_strncmp(script->hash, hash, REDIS_LUA_HASH_LENGTH)==0) {
          ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "REDIS SCRIPT ERROR: %s :%s", script->name, &reply->str[script_error_start.len + REDIS_LUA_HASH_LENGTH + 2]);
          return;
        }
      }
      ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "REDIS SCRIPT ERROR: (unknown): %s", reply->str);
    }
    else {
      ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "REDIS_REPLY_ERROR: %s", reply->str);
    }
  }
}

all-purpose debug output function via Redis ECHO command

local dbg = function(...) 
  local arg = {...}
  for i = 1, #arg do
    arg[i]=tostring(arg[i]) 
  end
  redis.call('ECHO', table.concat(arg, " ”))
end
copy, but don't plagiarise