int Server::appendGroupMsg(shared_ptr<IMChat::UnreadMsgRequest> ptrRequest, IMChat::UnreadMsgResponse& response) { auto ptrContext = m_redis.GetContext(); redisReply* ptrReply = NULL; string keyGroupSet("groupSet:"); keyGroupSet += ptrRequest->userid(); string keyNumber("unreadNumber:"); keyNumber += ptrRequest->userid(); keyNumber += ":*"; //查询各个群未读消息数目; //COMMAND: SORT groupSet:14006 GET # GET unreadNumber:14006:* vector<string> numberData; ptrReply = static_cast<redisReply*>(redisCommand(ptrContext, "SORT %s GET # GET %s", keyGroupSet.c_str(), keyNumber.c_str())); if (NULL != ptrReply && REDIS_REPLY_ARRAY == ptrReply->type && 0 != ptrReply->elements) { for (size_t i = 0; i < ptrReply->elements; i++) { numberData.push_back(string(ptrReply->element[i]->str, ptrReply->element[i]->len)); } } freeReplyObject(ptrReply); for (int i = 0; i < numberData.size()/2; i++) { if (numberData[2 * i + 1].compare("0") != 0) { //vector 数据第一个是groupId第二个是未读群消息数目; string listName("groupMsg:"); listName += numberData[2 * i]; redisAppendCommand(ptrContext, "LRANGE %s %d %s", listName.c_str(), 0, numberData[2 * i + 1]); } } //未读消息数; int nMsgNumber = 0; for (size_t i = 0; i < numberData.size()/2; i++) { if (numberData[2 * i + 1].compare("0") != 0) { redisGetReply(ptrContext, reinterpret_cast<void**>(&ptrReply)); if (NULL != ptrReply && REDIS_REPLY_ARRAY == ptrReply->type && 0 != ptrReply->elements) { for (size_t i = 0; i < ptrReply->elements; i++) { //添加repeated数据; response.add_msgdata()->assign(ptrReply->element[i]->str, ptrReply->element[i]->len); } nMsgNumber += ptrReply->elements; } freeReplyObject(ptrReply); } } //将未读消息数目置0; for (size_t i = 0; i < numberData.size() / 2; i++) { if (numberData[2 * i + 1].compare("0") != 0) { //Key unreadNumber:userid:groupid string key("unreadNumber:"); key += ptrRequest->userid(); key += ':'; key += numberData[2 * i]; m_redis.Set(key, "0"); } } return nMsgNumber; }
void run() { pid_t pid = -1; void *reply = NULL; const char *err_str = NULL; redisContext *c = redisConnect("127.0.0.1", 6379); if (!c || (c->err != 0)) goto ERR_CHNL_CONN; reply = redisCommand(c, "SUBSCRIBE %s", qUtf8Printable(m_cmd.m_info_chnl)); if (!reply) goto ERR_CHNL_SUB; freeReplyObject(reply); pid = fork(); if (pid == -1) goto ERR_FORK; else if (pid == 0) { execute_js(m_path, m_args, m_cmd); exit(0); return ; } emit m_cmd.started(); while (redisGetReply(c, &reply) == REDIS_OK) { struct redisReply *r = (struct redisReply *)reply; int ended = 0; if (r->type == REDIS_REPLY_ARRAY && r->elements == 3) { emit m_cmd.info(r->element[2]->str); if (strcmp("end", r->element[2]->str) == 0) { ended = 1; TEST_STOP = 1; // Question 1 : Need a extern visable to know program end or error // : So i use TEST_STOP control GUI "elapsed time" Start/ Stop } // add by Alwin //str_length_temp = strlen( r->element[2]->str ); // if message less 5 chara and elapsed time more than 2 second //if( str_length_temp > str_length ) // elpased time stop { //str_length = str_length_temp; //str_length_temp = 0; } emit m_cmd.justice_cmd_buf(); // Add by Alwin for GUI } freeReplyObject(reply); if (ended) break; } redisFree(c); kill(pid, SIGKILL); emit m_cmd.stopped(); waitpid(pid, NULL, 0); if( command_input_mode == 0 ) m_control_scroll = false; // add by Alwin return; ERR_FORK: err_str = "JS fork err."; ERR_CHNL_SUB: err_str = err_str == NULL ? "JS message channel subscribe err." : err_str; ERR_CHNL_CONN: err_str = err_str == NULL ? "JS message channel conn err." : err_str; if (c) redisFree(c); emit m_cmd.started(); emit m_cmd.err(err_str); emit m_cmd.stopped(); return; }
void addTarget() { // Setup static char absoluteAddress[64]; static char targetTag[64]; static char *extension; static char *fileName; // Clear array, avaoid issues int i; for (i = 0; i < 64; i++) absoluteAddress[i] = '\0'; printf("Enter full pathname of background image:\n"); printf("Path: "); // Get Filename fflush(stdin); fgets(absoluteAddress, sizeof(absoluteAddress), stdin); absoluteAddress[strcspn(absoluteAddress, "\n")] = '\0'; fflush(stdin); fflush(stdout); printf("Reading File: '%s' ", absoluteAddress); // Copy the string char absoluteAddressFileName[64]; char absoluteAddressExtension[64]; strcpy(absoluteAddressFileName, absoluteAddress); strcpy(absoluteAddressExtension, absoluteAddress); // Get the extension extension = strrchr(absoluteAddressExtension, '.'); // Get the filename fileName = strrchr(absoluteAddressFileName, '/'); fileName[strlen(fileName)-strlen(extension)] = '\0'; for (i = 0; i < strlen(fileName); i++) fileName[i] = fileName[i+1]; gdImagePtr target = loadImage(absoluteAddress, extension); if (target != NULL) { // Get Tag printf("\nEnter a tag for this target: "); fflush(stdin); fgets(targetTag, sizeof(targetTag), stdin); targetTag[strcspn(targetTag, "\n")] = '\0'; // Store data in directory storeImageTarget(target, ".png", TargetDIR, fileName, targetTag); // Store Tag redisReply *setReply = redisCommand(Context, "SADD %s %s", GRP_TARGET_NAME, targetTag); freeReplyObject(setReply); // Successful printf("Added to collection of background images\n"); } else { printf("Cannot Find Image.\n"); } free(target); }
void process( redisContext *c ) { FCGX_Stream *in, *out, *err; FCGX_ParamArray envp; redisReply *r; json reason = { .type = STRING, .name = "reason", .str = NULL }; json* failureEls[1] = { &reason }; json success = { .type = OBJECT, .length = 0, .name = NULL, .objArr = NULL }; json failure = { .type = OBJECT, .length = 1, .name = NULL, .objArr = failureEls }; while ( FCGX_Accept( &in, &out, &err, &envp ) >= 0 ) { // Check method if ( check_method_post( out, envp ) ) continue; // Check user is logged in char sid[33]; char *user = session( c, envp, sid ); if ( !user ) { header( out, 401, NULL ); reason.str = "Not logged in."; json_out( out, &failure ); continue; } // Initialize reused variables reason.str = ""; // Get contentlength long len = content_length( envp ); // Get post params char *s; if ( !read_stream( &s, in, len ) ) { header( out, 400, NULL ); reason.str = "No parameters provided"; json_out( out, &failure ); continue; } // Parse POST params param *p; ssize_t num = convert_to_params( &p, s, "&", "=", -1 ); // Get parameters char *courses = NULL, *date = NULL, *start = NULL, *finish = NULL, *students = NULL, *idStr = NULL; for ( int i = 0; i < num; ++i ) { if ( !courses && !strcmp( p[i].name, "courses" ) ) { courses = p[i].value; } else if ( !date && !strcmp( p[i].name, "date" ) ) { date = p[i].value; } else if ( !start && !strcmp( p[i].name, "start" ) ) { start = p[i].value; } else if ( !finish && !strcmp( p[i].name, "finish" ) ) { finish = p[i].value; } else if ( !students && !strcmp( p[i].name, "students" ) ) { students = p[i].value; } else if ( !idStr && !strcmp( p[i].name, "id" ) ) { idStr = p[i].value; } } // Check all parameters entered if ( !courses || !date || !start || !finish || !students ) { header( out, 400, NULL ); reason.str = "All details must be entered."; json_out( out, &failure ); goto err; } // URL decode components inplace_url_decode( courses ); inplace_url_decode( date ); inplace_url_decode( start ); inplace_url_decode( finish ); inplace_url_decode( students ); // Get next tute id long long id = -1; if ( idStr ) { // Convert to long long id = strtol( idStr, NULL, 10 ); // Check user owns tute r = redisCommand( c, "SISMEMBER tute:tutor:%s %lld", user, id ); if ( r->type != REDIS_REPLY_INTEGER ) { header( out, 500, NULL ); reason.str = "DB Error."; json_out( out, &failure ); freeReplyObject( r ); goto err; } if ( r->type != 1 ) { header( out, 400, NULL ); reason.str = "Invalid ID."; json_out( out, &failure ); freeReplyObject( r ); goto err; } } else { r = redisCommand( c, "INCR tute:tute:counter" ); if ( r->type != REDIS_REPLY_INTEGER ) { header( out, 500, NULL ); reason.str = "Could not fetch tute counter."; json_out( out, &failure ); freeReplyObject( r ); goto err; } id = r->integer; freeReplyObject( r ); } // Save tute r = redisCommand( c, "HMSET tute:tute:%lld tutor %s date %s start %s finish %s", id, user, date, start, finish ); if ( r->type == REDIS_REPLY_ERROR ) { header( out, 500, NULL ); reason.str = "Could not save tute."; json_out( out, &failure ); freeReplyObject( r ); goto err; } freeReplyObject( r ); // Save id to tutor r = redisCommand( c, "SADD tute:tutor:%s %lld", user, id ); if ( r->type == REDIS_REPLY_ERROR ) { header( out, 500, NULL ); reason.str = "Could not save tute."; json_out( out, &failure ); freeReplyObject( r ); goto err; } freeReplyObject( r ); // Parse codes param *course; ssize_t numCourses = convert_to_params( &course, courses, ";", ":", -1 ); num = numCourses; while ( num-- ) { // convert to lower to_lower( course[num].name ); // Save each code to tute id r = redisCommand( c, "SADD tute:tute:%lld:courses %s", id, course[num].name ); if ( r->type == REDIS_REPLY_ERROR ) { header( out, 500, NULL ); reason.str = "Could not save tute."; json_out( out, &failure ); freeReplyObject( r ); goto courseErr; } freeReplyObject( r ); // Add tute id to each code r = redisCommand( c, "SADD tute:course:%s:tutes %lld", course[num].name, id ); if ( r->type == REDIS_REPLY_ERROR ) { header( out, 500, NULL ); reason.str = "Could not save tute."; json_out( out, &failure ); freeReplyObject( r ); goto courseErr; } freeReplyObject( r ); } // Parse students param *student; num = convert_to_params( &student, students, ";", ":", -1 ); while ( num-- ) { // Add each student to tute r = redisCommand( c, "SADD tute:tute:%lld:students %s", id, student[num].name ); if ( r->type == REDIS_REPLY_ERROR ) { header( out, 500, NULL ); reason.str = "Could not save tute."; json_out( out, &failure ); freeReplyObject( r ); goto studentErr; } freeReplyObject( r ); // Save student data param *data; ssize_t fields = convert_to_params( &data, student[num].value, ",", "|", -1 ); if ( fields ) { char *college = NULL, *first = NULL, *last = NULL; while ( fields-- ) { if ( !college && !strcmp( data[fields].name, "college" ) ) { college = data[fields].value; } else if ( !first && !strcmp( data[fields].name, "first" ) ) { first = data[fields].value; } else if ( !last && !strcmp( data[fields].name, "last" ) ) { last = data[fields].value; } } if ( college && first && last ) { r = redisCommand( c, "HMSET tute:student:%s college %s first %s last %s", student[num].name, college, first, last ); if ( r->type == REDIS_REPLY_ERROR ) { header( out, 500, NULL ); reason.str = "Could not save tute."; json_out( out, &failure ); freeReplyObject( r ); free( data ); goto studentErr; } freeReplyObject( r ); } free( data ); } // Add tute id to each student r = redisCommand( c, "SADD tute:attendee:%s %lld", student[num].name, id ); if ( r->type == REDIS_REPLY_ERROR ) { header( out, 500, NULL ); reason.str = "Could not save tute."; json_out( out, &failure ); freeReplyObject( r ); goto studentErr; } freeReplyObject( r ); // Add student to each course ssize_t n = numCourses; while ( n-- ) { r = redisCommand( c, "SADD tute:course:%s:students %s", course[n].name, student[num].name ); if ( r->type == REDIS_REPLY_ERROR ) { header( out, 500, NULL ); reason.str = "Could not save tute."; json_out( out, &failure ); freeReplyObject( r ); goto studentErr; } freeReplyObject( r ); } } // Output success header( out, 200, sid ); json_out( out, &success ); studentErr: free( student ); // free params structure courseErr: free( course ); err: free( user ); free( p ); // Free params structure free( s ); // Free POST stream } } int main ( int argc, char *argv[] ) { return init( &process ); }
int redis_lookup(char *response, redisPool *pool, char *key) { int fd; redisReply *reply; char replyStr[64] = ""; char registry[64] = ""; time_t client_time; time_t reset; int rest; time(&client_time); /* if the event time is greater then the init_time */ rest = ((int) client_time - init_time); if(rest > cfg.redis_reload_time) { syslog(LOG_INFO, "%i passed. Realoading database\n", cfg.redis_reload_time); if(redisPoolInit(&redis_pool, cfg.redis_address, REDIS_POOL_SIZE) == -1) { snprintf(replyStr, (size_t) strlen(POSTFIX_RESPONSE_TEMPFAIL) + 20, "%s %s\n", POSTFIX_RESPONSE_TEMPFAIL, "reset database error"); } /* reset the counter */ time(&reset); init_time = (int) reset; } fd = redisPoolGetCurrent(pool); /* running the string cfg.registry_prefix to know what kinds of service i'll answer. */ int i, scount = 0; for(i = 0; i<=strlen(cfg.registry_prefix); i++) { /* when i found a comma or a string ending, issue the command */ if((cfg.registry_prefix[i] == ',') || cfg.registry_prefix[i] == '\0') { registry[scount] = '\0'; reply = redisCommand(fd, "GET %b:%b", registry, strlen(registry), key, strlen(key)); /* if the reply is not nil, break the loop. * Case is nil, continue until the end */ if(reply->type != REDIS_REPLY_NIL) break; scount = 0; registry[0] = '\0'; continue; } registry[scount] = cfg.registry_prefix[i]; scount++; } if(reply->type == REDIS_REPLY_ERROR) { /* if disconected, try reconnect */ if(redisPoolInit(&redis_pool, cfg.redis_address, REDIS_POOL_SIZE) == -1) { snprintf(replyStr, (size_t) strlen(POSTFIX_RESPONSE_TEMPFAIL) + strlen(reply->reply) +3, "%s %s\n", POSTFIX_RESPONSE_TEMPFAIL, reply->reply); } else { /* if reconnected, select current */ fd = redisPoolGetCurrent(&redis_pool); /* re-send the request */ reply = redisCommand(fd, "GET %b:%b", registry, strlen(registry), key, strlen(key)); snprintf(replyStr, (size_t) strlen(POSTFIX_RESPONSE_OK) + strlen(reply->reply) +3, "%s %s\n", POSTFIX_RESPONSE_OK, reply->reply); } } else { /* time the reply to client */ if(reply->type != REDIS_REPLY_NIL) { /* if is a string (in this case, always) */ if(reply->type == REDIS_REPLY_STRING) { snprintf(replyStr, (size_t) strlen(POSTFIX_RESPONSE_OK) + strlen(reply->reply) +3, "%s %s", POSTFIX_RESPONSE_OK, reply->reply); } } /* if the entry does not exists, reply 500 to client */ /* update: return -1, to query a dbms */ else { freeReplyObject(reply); return -1; /*snprintf(replyStr, (size_t) strlen(POSTFIX_RESPONSE_ERROR) + 16, "%s %s", POSTFIX_RESPONSE_ERROR, "unknown entry");*/ } } syslog(LOG_INFO, "Reply sent to client: (%s)", replyStr); /* freeing response */ freeReplyObject(reply); /* pasting into *response */ sprintf(response, "%s\n", replyStr); return 0; }
static void test_blocking_connection(struct config config) { redisContext *c; redisReply *reply; c = connect(config); test("Is able to deliver commands: "); reply = redisCommand(c,"PING"); test_cond(reply->type == REDIS_REPLY_STATUS && strcasecmp(reply->str,"pong") == 0) freeReplyObject(reply); test("Is a able to send commands verbatim: "); reply = redisCommand(c,"SET foo bar"); test_cond (reply->type == REDIS_REPLY_STATUS && strcasecmp(reply->str,"ok") == 0) freeReplyObject(reply); test("%%s String interpolation works: "); reply = redisCommand(c,"SET %s %s","foo","hello world"); freeReplyObject(reply); reply = redisCommand(c,"GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && strcmp(reply->str,"hello world") == 0); freeReplyObject(reply); test("%%b String interpolation works: "); reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11); freeReplyObject(reply); reply = redisCommand(c,"GET foo"); test_cond(reply->type == REDIS_REPLY_STRING && memcmp(reply->str,"hello\x00world",11) == 0) test("Binary reply length is correct: "); test_cond(reply->len == 11) freeReplyObject(reply); test("Can parse nil replies: "); reply = redisCommand(c,"GET nokey"); test_cond(reply->type == REDIS_REPLY_NIL) freeReplyObject(reply); /* test 7 */ test("Can parse integer replies: "); reply = redisCommand(c,"INCR mycounter"); test_cond(reply->type == REDIS_REPLY_INTEGER && reply->integer == 1) freeReplyObject(reply); test("Can parse multi bulk replies: "); freeReplyObject(redisCommand(c,"LPUSH mylist foo")); freeReplyObject(redisCommand(c,"LPUSH mylist bar")); reply = redisCommand(c,"LRANGE mylist 0 -1"); test_cond(reply->type == REDIS_REPLY_ARRAY && reply->elements == 2 && !memcmp(reply->element[0]->str,"bar",3) && !memcmp(reply->element[1]->str,"foo",3)) freeReplyObject(reply); /* m/e with multi bulk reply *before* other reply. * specifically test ordering of reply items to parse. */ test("Can handle nested multi bulk replies: "); freeReplyObject(redisCommand(c,"MULTI")); freeReplyObject(redisCommand(c,"LRANGE mylist 0 -1")); freeReplyObject(redisCommand(c,"PING")); reply = (redisCommand(c,"EXEC")); test_cond(reply->type == REDIS_REPLY_ARRAY && reply->elements == 2 && reply->element[0]->type == REDIS_REPLY_ARRAY && reply->element[0]->elements == 2 && !memcmp(reply->element[0]->element[0]->str,"bar",3) && !memcmp(reply->element[0]->element[1]->str,"foo",3) && reply->element[1]->type == REDIS_REPLY_STATUS && strcasecmp(reply->element[1]->str,"pong") == 0); freeReplyObject(reply); disconnect(c, 0); }
/** Insert a new entry into the data store * * @copydetails cache_entry_insert_t */ static cache_status_t cache_entry_insert(UNUSED rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, UNUSED void *handle, const rlm_cache_entry_t *c) { rlm_cache_redis_t *driver = driver_inst; TALLOC_CTX *pool; vp_map_t *map; fr_redis_conn_t *conn; fr_redis_cluster_state_t state; fr_redis_rcode_t status; redisReply *reply = NULL; int s_ret; static char const command[] = "RPUSH"; char const **argv; size_t *argv_len; char const **argv_p; size_t *argv_len_p; int pipelined = 0; /* How many commands pending in the pipeline */ redisReply *replies[5]; /* Should have the same number of elements as pipelined commands */ size_t reply_num = 0, i; char *p; int cnt; vp_tmpl_t expires_value; vp_map_t expires = { .op = T_OP_SET, .lhs = &driver->expires_attr, .rhs = &expires_value, }; vp_tmpl_t created_value; vp_map_t created = { .op = T_OP_SET, .lhs = &driver->created_attr, .rhs = &created_value, .next = &expires }; /* * Encode the entry created date */ tmpl_init(&created_value, TMPL_TYPE_DATA, "<TEMP>", 6, T_BARE_WORD); created_value.tmpl_data_type = PW_TYPE_DATE; created_value.tmpl_data_length = sizeof(created_value.tmpl_data_value.date); created_value.tmpl_data_value.date = c->created; /* * Encode the entry expiry time * * Although Redis objects expire on their own, we still need this * to ignore entries that were created before the last epoch. */ tmpl_init(&expires_value, TMPL_TYPE_DATA, "<TEMP>", 6, T_BARE_WORD); expires_value.tmpl_data_type = PW_TYPE_DATE; expires_value.tmpl_data_length = sizeof(expires_value.tmpl_data_value.date); expires_value.tmpl_data_value.date = c->expires; expires.next = c->maps; /* Head of the list */ for (cnt = 0, map = &created; map; cnt++, map = map->next); /* * The majority of serialized entries should be under 1k. * * @todo We should really calculate this using some sort of moving average. */ pool = talloc_pool(request, 1024); if (!pool) return CACHE_ERROR; argv_p = argv = talloc_array(pool, char const *, (cnt * 3) + 2); /* pair = 3 + cmd + key */ argv_len_p = argv_len = talloc_array(pool, size_t, (cnt * 3) + 2); /* pair = 3 + cmd + key */ *argv_p++ = command; *argv_len_p++ = sizeof(command) - 1; *argv_p++ = (char const *)c->key; *argv_len_p++ = c->key_len; /* * Add the maps to the command string in reverse order */ for (map = &created; map; map = map->next) { if (fr_redis_tuple_from_map(pool, argv_p, argv_len_p, map) < 0) { REDEBUG("Failed encoding map as Redis K/V pair"); talloc_free(pool); return CACHE_ERROR; } argv_p += 3; argv_len_p += 3; } RDEBUG3("Pipelining commands"); RINDENT(); for (s_ret = fr_redis_cluster_state_init(&state, &conn, driver->cluster, request, c->key, c->key_len, false); s_ret == REDIS_RCODE_TRY_AGAIN; /* Continue */ s_ret = fr_redis_cluster_state_next(&state, &conn, driver->cluster, request, status, &reply)) { /* * Start the transaction, as we need to set an expiry time too. */ if (c->expires > 0) { RDEBUG3("MULTI"); if (redisAppendCommand(conn->handle, "MULTI") != REDIS_OK) { append_error: REXDENT(); RERROR("Failed appending Redis command to output buffer: %s", conn->handle->errstr); talloc_free(pool); return CACHE_ERROR; } pipelined++; } if (RDEBUG_ENABLED3) { p = fr_asprint(request, (char const *)c->key, c->key_len, '\0'); RDEBUG3("DEL \"%s\"", p); talloc_free(p); } if (redisAppendCommand(conn->handle, "DEL %b", c->key, c->key_len) != REDIS_OK) goto append_error; pipelined++; if (RDEBUG_ENABLED3) { RDEBUG3("argv command"); RINDENT(); for (i = 0; i < talloc_array_length(argv); i++) { p = fr_asprint(request, argv[i], argv_len[i], '\0'); RDEBUG3("%s", p); talloc_free(p); } REXDENT(); } redisAppendCommandArgv(conn->handle, talloc_array_length(argv), argv, argv_len); pipelined++; /* * Set the expiry time and close out the transaction. */ if (c->expires > 0) { if (RDEBUG_ENABLED3) { p = fr_asprint(request, (char const *)c->key, c->key_len, '\"'); RDEBUG3("EXPIREAT \"%s\" %li", p, (long)c->expires); talloc_free(p); } if (redisAppendCommand(conn->handle, "EXPIREAT %b %i", c->key, c->key_len, c->expires) != REDIS_OK) goto append_error; pipelined++; RDEBUG3("EXEC"); if (redisAppendCommand(conn->handle, "EXEC") != REDIS_OK) goto append_error; pipelined++; } REXDENT(); reply_num = fr_redis_pipeline_result(&status, replies, sizeof(replies) / sizeof(*replies), conn, pipelined); reply = replies[0]; } talloc_free(pool); if (s_ret != REDIS_RCODE_SUCCESS) { RERROR("Failed inserting entry"); return CACHE_ERROR; } RDEBUG3("Command results"); RINDENT(); for (i = 0; i < reply_num; i++) { fr_redis_reply_print(L_DBG_LVL_3, replies[i], request, i); fr_redis_reply_free(replies[i]); } REXDENT(); return CACHE_OK; } /** Call delete the cache entry from redis * * @copydetails cache_entry_expire_t */ static cache_status_t cache_entry_expire(UNUSED rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, UNUSED void *handle, uint8_t const *key, size_t key_len) { rlm_cache_redis_t *driver = driver_inst; fr_redis_cluster_state_t state; fr_redis_conn_t *conn; fr_redis_rcode_t status; redisReply *reply = NULL; int s_ret; for (s_ret = fr_redis_cluster_state_init(&state, &conn, driver->cluster, request, key, key_len, false); s_ret == REDIS_RCODE_TRY_AGAIN; /* Continue */ s_ret = fr_redis_cluster_state_next(&state, &conn, driver->cluster, request, status, &reply)) { reply = redisCommand(conn->handle, "DEL %b", key, key_len); status = fr_redis_command_status(conn, reply); } if (s_ret != REDIS_RCODE_SUCCESS) { RERROR("Failed expiring entry"); fr_redis_reply_free(reply); return CACHE_ERROR; } rad_assert(reply); /* clang scan */ if (reply->type == REDIS_REPLY_INTEGER) { fr_redis_reply_free(reply); if (reply->integer) return CACHE_OK; /* Affected */ return CACHE_MISS; } REDEBUG("Bad result type, expected integer, got %s", fr_int2str(redis_reply_types, reply->type, "<UNKNOWN>")); fr_redis_reply_free(reply); return CACHE_ERROR; } extern cache_driver_t rlm_cache_redis; cache_driver_t rlm_cache_redis = { .name = "rlm_cache_redis", .instantiate = mod_instantiate, .inst_size = sizeof(rlm_cache_redis_t), .free = cache_entry_free, .find = cache_entry_find, .insert = cache_entry_insert, .expire = cache_entry_expire, };
int redis_connect(redis_con *con) { redisContext *ctx; redisReply *rpl; cluster_node *it; /* connect to redis DB */ ctx = redisConnect(con->id->host,con->id->port); if (ctx->err != REDIS_OK) { LM_ERR("failed to open redis connection - %s\n",ctx->errstr); return -1; } /* auth using password, if any */ if (con->id->password) { rpl = redisCommand(ctx,"AUTH %s",con->id->password); if (rpl == NULL || rpl->type == REDIS_REPLY_ERROR) { LM_ERR("failed to auth to redis - %.*s\n", rpl?rpl->len:7,rpl?rpl->str:"FAILURE"); freeReplyObject(rpl); redisFree(ctx); return -1; } LM_DBG("AUTH [password] - %.*s\n",rpl->len,rpl->str); freeReplyObject(rpl); } rpl = redisCommand(ctx,"CLUSTER NODES"); if (rpl == NULL || rpl->type == REDIS_REPLY_ERROR) { /* single instace mode */ con->type |= REDIS_SINGLE_INSTANCE; con->nodes = pkg_malloc(sizeof(cluster_node)); if (con->nodes == NULL) { LM_ERR("no more pkg\n"); freeReplyObject(rpl); redisFree(ctx); return -1; } strcpy(con->nodes->ip,con->id->host); con->nodes->port = con->id->port; con->nodes->start_slot = 0; con->nodes->end_slot = 4096; con->nodes->context = NULL; con->nodes->next = NULL; LM_DBG("single instance mode\n"); } else { /* cluster instance mode */ con->type |= REDIS_CLUSTER_INSTANCE; con->slots_assigned = 0; LM_DBG("cluster instance mode\n"); if (build_cluster_nodes(con,rpl->str,rpl->len) < 0) { LM_ERR("failed to parse Redis cluster info\n"); return -1; } } freeReplyObject(rpl); redisFree(ctx); for (it=con->nodes;it;it=it->next) { if (it->end_slot > con->slots_assigned ) con->slots_assigned = it->end_slot; if (redis_connect_node(con,it) < 0) { LM_ERR("failed to init connection \n"); return -1; } } return 0; }
static void findBigKeys(void) { unsigned long long biggest[5] = {0,0,0,0,0}; unsigned long long samples = 0; redisReply *reply1, *reply2, *reply3 = NULL; char *sizecmd, *typename[] = {"string","list","set","hash","zset"}; int type; printf("\n# Press ctrl+c when you have had enough of it... :)\n"); printf("# You can use -i 0.1 to sleep 0.1 sec every 100 sampled keys\n"); printf("# in order to reduce server load (usually not needed).\n\n"); while(1) { /* Sample with RANDOMKEY */ reply1 = redisCommand(context,"RANDOMKEY"); if (reply1 == NULL) { fprintf(stderr,"\nI/O error\n"); exit(1); } else if (reply1->type == REDIS_REPLY_ERROR) { fprintf(stderr, "RANDOMKEY error: %s\n", reply1->str); exit(1); } /* Get the key type */ reply2 = redisCommand(context,"TYPE %s",reply1->str); assert(reply2 && reply2->type == REDIS_REPLY_STATUS); samples++; /* Get the key "size" */ if (!strcmp(reply2->str,"string")) { sizecmd = "STRLEN"; type = TYPE_STRING; } else if (!strcmp(reply2->str,"list")) { sizecmd = "LLEN"; type = TYPE_LIST; } else if (!strcmp(reply2->str,"set")) { sizecmd = "SCARD"; type = TYPE_SET; } else if (!strcmp(reply2->str,"hash")) { sizecmd = "HLEN"; type = TYPE_HASH; } else if (!strcmp(reply2->str,"zset")) { sizecmd = "ZCARD"; type = TYPE_ZSET; } else if (!strcmp(reply2->str,"none")) { freeReplyObject(reply1); freeReplyObject(reply2); freeReplyObject(reply3); continue; } else { fprintf(stderr, "Unknown key type '%s' for key '%s'\n", reply2->str, reply1->str); exit(1); } reply3 = redisCommand(context,"%s %s", sizecmd, reply1->str); if (reply3 && reply3->type == REDIS_REPLY_INTEGER) { if (biggest[type] < reply3->integer) { printf("[%6s] %s | biggest so far with size %llu\n", typename[type], reply1->str, (unsigned long long) reply3->integer); biggest[type] = reply3->integer; } } if ((samples % 1000000) == 0) printf("(%llu keys sampled)\n", samples); if ((samples % 100) == 0 && config.interval) usleep(config.interval); freeReplyObject(reply1); freeReplyObject(reply2); if (reply3) freeReplyObject(reply3); } }
/* * === FUNCTION ====================================================================== * Name: int log_vgtp_pe_sync() * Description: logging VGTP performance parameters * ===================================================================================== */ int log_vgtp_pe_sync(int s_id, char *s_desc, int data_len, char* data_val) { //Check the input parameters DBG("Check the input parameters.\n"); if(0 > s_id){ printf("Input parameters error: s_id = %d.\n", s_id); return -1; } if(NULL==s_desc){ printf("Input parameters error: s_desc = NULL.\n"); return -2; } if(0>=data_len || data_len >= REDIS_CMD_BUFFER_LEN){ printf("Input parameters error: data_len = %d.\n", data_len); return -3; } if(NULL==data_val){ printf("Input parameters error: data_val = NULL.\n"); return -4; } if(data_len != (int)strlen(data_val) ){ printf("Input parameters error: len(data_val) = %d and data_len = %d.\n", strlen(data_val), data_len); return -5; } //Connect the Redis Database DBG("Prepare Redis DB:\n"); redisContext *redis_con = NULL; redisReply *redis_reply = NULL; const char * redis_hostname = REDIS_SRV_IP; int redis_port = REDIS_SRV_PORT; struct timeval redis_timeout = {1, REDIS_TIMEOUT}; redis_con = redisConnectWithTimeout(redis_hostname, redis_port, redis_timeout); if(NULL==redis_con || redis_con->err) { if(redis_con) { printf("Redis connection error: %s\n", redis_con->errstr); redisFree(redis_con); redis_con = NULL; } else { printf("Redis Connection error: can't allocate redis context.\n"); } return -1; } else { DBG("Redis Connection Success.\n"); redis_reply = (redisReply*)redisCommand(redis_con, "Ping"); DBG("Ping: %s\n", redis_reply->str); freeReplyObject(redis_reply); redis_reply= NULL; } //Save the performance parameters into Redis DB. char cmd_buffer[REDIS_CMD_BUFFER_LEN]; memset((void*)cmd_buffer, 0, REDIS_CMD_BUFFER_LEN); sprintf(cmd_buffer, "ID:%d|DESC:%s|%s", s_id, s_desc, data_val); DBG("cmd_buffer: %s\n", cmd_buffer); redis_reply = (redisReply*)redisCommand(redis_con, "rpush %s %b", REDIS_PE_STAT_LIST, cmd_buffer, (size_t)strlen(cmd_buffer)); if(NULL == redis_reply ||redis_reply->type == REDIS_REPLY_ERROR ||redis_reply->type == REDIS_REPLY_NIL) { printf("RedisDB reply is NULL or ErrCode = |%s|", redis_reply->str); return -1; } //free redis_reply objects if(NULL != redis_reply) { freeReplyObject(redis_reply); redis_reply = NULL; } //free redis conn if(NULL != redis_con){ redisFree(redis_con); redis_con = NULL; } return 1; }
void print_key2(redis_instance* inst, char* key, size_t len) { long long size = 0; int flag = get_key_type(inst, key, len); long long pttl = get_key_pttl(inst, key, len); printf("{key:%s, type:%s, pttl:%lldms, db:%lu,", key, type_name[flag], pttl, inst->db); switch (flag) { case KSTRING: { redisReply* kv = (redisReply*)redisCommand(inst->cxt, "get %b", key, len); assert(kv != nil); assert(kv->type == REDIS_REPLY_STRING); assert(kv->len != 0); pline(" value:%s}", kv->str); freeReplyObject(kv); } break; case KHASH: { size = get_hashtable_size(inst, key, len); printf(" size:%lld", size); if (size) { printf(",\n kvs:["); print_hashtable2(inst, key, len); pline("\b \n ]"); } pline("}"); } break; case KLIST: { size = get_list_size(inst, key, len); printf(" size:%lld", size); if (size) { printf(",\n values:["); print_list(inst, key, len); pline("\b \n ]"); } pline("}"); } break; case KSET: { size = get_set_size(inst, key, len); printf(" size:%lld", size); if (size) { printf(",\n values:["); print_set2(inst, key, len); pline("\b \n ]"); } pline("}"); } break; case KSSET: { size = get_sset_size(inst, key, len); printf(" size:%lld", size); if (size) { printf(",\n values:["); print_sset2(inst, key, len); pline("\b \n ]"); } pline("}"); } break; case KNONE: { FATAL("none type of key:%s", key); } break; case KUNKOWN: { FATAL("unknown type of key:%s", key); } } }
int main(int argc, char **argv) { redisContext *c; redisReply *reply; const char *socket = NULL; const char *ip = "127.0.0.1"; int port = 3388; const char *topic = "loggen"; int num = -1; int period = -1; int i = 0; void *kid = NULL; char logbuf[10240]; int opt; int quiet = 0; int psub = 0; const char* const short_options = "s:i:p:t:f:n:qbh"; const struct option long_options[] = { { "socket", required_argument, NULL, 's' }, { "ip", required_argument, NULL, 'i' }, { "port", required_argument, NULL, 'p' }, { "topic", required_argument, NULL, 't' }, { "psub", no_argument, NULL, 'b' }, { "num", required_argument, NULL, 'n' }, { "period", required_argument, NULL, 'r' }, { "quiet", no_argument, NULL, 'q' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 }, }; while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) > 0) { switch (opt) { case 's': socket = optarg; break; case 'i': ip = optarg; break; case 'p': port = atoi(optarg); break; case 't': topic = optarg; break; case 'b': psub = 1; break; case 'n': num = atoi(optarg); break; case 'r': period = atoi(optarg); break; case 'q': quiet = 1; break; case 'h': default: Usage(argv[0]); } } if (socket == NULL && ip == NULL) { Usage(argv[0]); } struct timeval timeout = { 1, 500000 }; // 1.5 seconds if (socket) { c = redisConnectUnixWithTimeout(socket, timeout); } else { c = redisConnectWithTimeout((char*)ip, port, timeout); } if (c->err) { printf("Connection error: %s\n", c->errstr); exit(1); } if (psub) reply = redisCommand(c,"PSUBSCRIBE %s", topic); else reply = redisCommand(c,"SUBSCRIBE %s", topic); if (reply) { printf("SUBSCRIBE %s\n", reply->str); freeReplyObject(reply); } while (1) { if (!redisGetReply(c, (void*)&reply)) { printf("%s %s %s", reply->element[0]->str, reply->element[1]->str, reply->element[2]->str); if (psub) printf("%s", reply->element[3]->str); printf("\n"); freeReplyObject(reply); } else { printf("get msg failed\n"); } if (period != -1) { usleep(period * 1000); } } redisFree(c); }
redisReply * modred_command(const char *command,redisContext *context) { redisReply * reply=redisCommand(context,command); return reply; }
int main(int argc, char *argv[]) { int ret = 1; size_t bufSize = 8192; int batchSize = 2000; if (argc > 1) { batchSize = atoi(argv[1]); if (batchSize <= 0) { fprintf(stderr, "Dodgy batch size\n"); exit(1); } } char *buffer = calloc(bufSize, sizeof(char)); uint64_t cnt = 0; redisReply *reply = NULL; redisContext *c = redisConnectUnix("/var/lib/redis/redis.sock"); if (c != NULL && c->err) { printf("Error: %s\n", c->errstr); goto cleanup; } reply = redisCommand(c, "DEL testhll"); if (reply == NULL) { printf("Failed: %s\n", c->errstr); goto cleanup; } freeReplyObject(reply); int batchPos = 0; int len = 0; while ((len = readln(stdin, '\n', &buffer, &bufSize)) > 0) { cnt++; redisAppendCommand(c, "PFADD testhll %s", buffer); batchPos++; if (batchSize == batchPos) { batchPos = 0; for (int j = 0; j < batchSize; j++) { redisGetReply(c, (void **)&reply); if (reply == NULL) { printf("Failed: %s\n", c->errstr); goto cleanup; } else if (reply->type == REDIS_REPLY_ERROR) { printf("Failed: %s\n", reply->str); goto cleanup; } freeReplyObject(reply); } } } if (batchPos > 0) { for (int j = 0; j < batchPos; j++) { redisGetReply(c, (void **)&reply); if (reply == NULL) { printf("Failed: %s\n", c->errstr); goto cleanup; } else if (reply->type == REDIS_REPLY_ERROR) { printf("Failed: %s\n", reply->str); goto cleanup; } freeReplyObject(reply); } } reply = redisCommand(c, "PFCOUNT testhll"); if (reply == NULL) { printf("Failed: %s\n", c->errstr); goto cleanup; } printf("%ld %lld\n", cnt, reply->integer); ret = 0; cleanup: if (reply != NULL) freeReplyObject(reply); free(buffer); redisFree(c); return ret; }
int main(void) { unsigned int j; redisContext *c; redisReply *reply; struct timeval timeout = { 1, 500000 }; // 1.5 seconds c = redisConnectWithTimeout((char*)"127.0.0.1", 6379, timeout); if (c->err) { printf("Connection error: %s\n", c->errstr); exit(1); } /* PING server */ reply = redisCommand(c,"PING"); printf("PING: %s\n", reply->str); freeReplyObject(reply); /* Set a key */ reply = redisCommand(c,"SET %s %s", "foo", "hello world"); printf("SET: %s\n", reply->str); freeReplyObject(reply); /* Set a key using binary safe API */ reply = redisCommand(c,"SET %b %b", "bar", (size_t)3, "hello", (size_t)5); printf("SET (binary API): %s\n", reply->str); freeReplyObject(reply); /* Try a GET and two INCR */ reply = redisCommand(c,"GET foo"); printf("GET foo: %s\n", reply->str); freeReplyObject(reply); reply = redisCommand(c,"INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* again ... */ reply = redisCommand(c,"INCR counter"); printf("INCR counter: %lld\n", reply->integer); freeReplyObject(reply); /* Create a list of numbers, from 0 to 9 */ reply = redisCommand(c,"DEL mylist"); freeReplyObject(reply); for (j = 0; j < 10; j++) { char buf[64]; snprintf(buf,64,"%d",j); reply = redisCommand(c,"LPUSH mylist element-%s", buf); freeReplyObject(reply); } /* Let's check what we have inside the list */ reply = redisCommand(c,"LRANGE mylist 0 -1"); if (reply->type == REDIS_REPLY_ARRAY) { for (j = 0; j < reply->elements; j++) { printf("%u) %s\n", j, reply->element[j]->str); } } freeReplyObject(reply); return 0; }
static void test_nonblocking_connection() { redisContext *c; int wdone = 0; test("Calls command callback when command is issued: "); c = __connect_nonblock(); redisSetCommandCallback(c,__test_callback,(void*)1); redisCommand(c,"PING"); test_cond(__test_callback_flags == 1); redisFree(c); test("Calls disconnect callback on redisDisconnect: "); c = __connect_nonblock(); redisSetDisconnectCallback(c,__test_callback,(void*)2); redisDisconnect(c); test_cond(__test_callback_flags == 2); redisFree(c); test("Calls disconnect callback and free callback on redisFree: "); c = __connect_nonblock(); redisSetDisconnectCallback(c,__test_callback,(void*)2); redisSetFreeCallback(c,__test_callback,(void*)4); redisFree(c); test_cond(__test_callback_flags == ((2 << 8) | 4)); test("redisBufferWrite against empty write buffer: "); c = __connect_nonblock(); test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1); redisFree(c); test("redisBufferWrite against not yet connected fd: "); c = __connect_nonblock(); redisCommand(c,"PING"); test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && strncmp(c->error,"write:",6) == 0); redisFree(c); test("redisBufferWrite against closed fd: "); c = __connect_nonblock(); redisCommand(c,"PING"); redisDisconnect(c); test_cond(redisBufferWrite(c,NULL) == REDIS_ERR && strncmp(c->error,"write:",6) == 0); redisFree(c); test("Process callbacks in the right sequence: "); c = __connect_nonblock(); redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING"); redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING"); /* Write output buffer */ wdone = 0; while(!wdone) { usleep(500); redisBufferWrite(c,&wdone); } /* Read until at least one callback is executed (the 3 replies will * arrive in a single packet, causing all callbacks to be executed in * a single pass). */ while(__test_callback_flags == 0) { assert(redisBufferRead(c) == REDIS_OK); redisProcessCallbacks(c); } test_cond(__test_callback_flags == 0x010203); redisFree(c); test("redisDisconnect executes pending callbacks with NULL reply: "); c = __connect_nonblock(); redisSetDisconnectCallback(c,__test_callback,(void*)1); redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING"); redisDisconnect(c); test_cond(__test_callback_flags == 0x0201); redisFree(c); }
int main(int argc, char **argv){ int i, j, n, similarityFunc = 0; int itemCount = 0; char *itemID; char *redisPrefix; redisContext *c; redisReply *all_items; redisReply *reply; int cur_batch_size; char* cur_batch; char *iikey; int batch_size = 200; /* FIXPAUL: make option */ int maxItems = 50; /* FIXPAUL: make option */ struct { char host[1024]; int port; char db[64]; } redis_addr; /* option parsing */ if(argc < 2) return print_usage(argv[0]); if(!strcmp(argv[1], "--version")) return print_version(); if(!strcmp(argv[1], "--jaccard")) similarityFunc = 1; if(!strcmp(argv[1], "--cosine")) similarityFunc = 2; if(!similarityFunc){ printf("invalid option: %s\n", argv[1]); return 1; } else if(argc < 5 || argc > 6){ printf("wrong number of arguments\n"); print_usage(argv[0]); return 1; } redisPrefix = argv[2]; itemID = argv[3]; redis_addr.host[0] = 0; redis_addr.port = 0; redis_addr.db[0] = 0; /* configure redis location */ if(argc > 4){ char* has_port = strchr(argv[4], ':'); if(has_port){ strncpy(redis_addr.host, argv[4], strlen(argv[4]) - strlen(has_port)); redis_addr.host[strlen(argv[4]) - strlen(has_port)] = 0; redis_addr.port = atoi(has_port + 1); } else { strncpy(redis_addr.host, argv[4], sizeof(redis_addr.host)); } } if(argc > 5){ strcpy(redis_addr.db, argv[5]); } else { strcpy(redis_addr.db, "0"); } /* default redis location */ if(strlen(redis_addr.host) == 0) strcpy(redis_addr.host, "localhost"); if(!redis_addr.port) redis_addr.port = 6379; /* connect to redis */ struct timeval timeout = { 1, 500000 }; c = redisConnectWithTimeout(redis_addr.host, redis_addr.port, timeout); redisCommand(c, "SELECT %s", redis_addr.db); if(c->err){ printf("connection to redis failed: %s\n", c->errstr); return 1; } /* get item count */ reply = redisCommand(c,"HGET %s:items %s", redisPrefix, itemID); if(reply->str){ itemCount = atoi(reply->str); } else { itemCount = 0; } freeReplyObject(reply); if(itemCount < 2){ printf("exit: item count is zero or one\n"); return 0; } /* get all items_ids and the total counts */ all_items = redisCommand(c,"HGETALL %s:items", redisPrefix); if(all_items->type != REDIS_REPLY_ARRAY) return 1; /* populate the cc_items array */ int cc_items_size = all_items->elements / 2; int cc_items_mem = cc_items_size * sizeof(struct cc_item); struct cc_item *cc_items = malloc(cc_items_mem); cc_items_size--; if(!cc_items){ printf("cannot allocate memory: %i", cc_items_mem); return 1; } i = 0; for (j = 0; j < all_items->elements/2; j++){ if(strcmp(itemID, all_items->element[j*2]->str) != 0){ strncpy(cc_items[i].item_id, all_items->element[j*2]->str, ITEM_ID_SIZE); cc_items[i].total_count = atoi(all_items->element[j*2+1]->str); i++; } } freeReplyObject(all_items); // batched redis hmgets on the ccmatrix cur_batch = (char *)malloc(((batch_size * (ITEM_ID_SIZE + 4) * 2) + 100) * sizeof(char)); if(!cur_batch){ printf("cannot allocate memory"); return 1; } n = cc_items_size; while(n >= 0){ cur_batch_size = ((n-1 < batch_size) ? n-1 : batch_size); sprintf(cur_batch, "HMGET %s:ccmatrix ", redisPrefix); for(i = 0; i < cur_batch_size; i++){ iikey = item_item_key(itemID, cc_items[n-i].item_id); strcat(cur_batch, iikey); strcat(cur_batch, " "); if(iikey) free(iikey); } redisAppendCommand(c, cur_batch); redisGetReply(c, (void**)&reply); for(j = 0; j < reply->elements; j++){ if(reply->element[j]->str){ cc_items[n-j].coconcurrency_count = atoi(reply->element[j]->str); } else { cc_items[n-j].coconcurrency_count = 0; } } freeReplyObject(reply); n -= batch_size; } free(cur_batch); /* calculate similarities */ if(similarityFunc == 1) calculate_jaccard(itemID, itemCount, cc_items, cc_items_size); if(similarityFunc == 2) calculate_cosine(itemID, itemCount, cc_items, cc_items_size); /* find the top x items with simple bubble sort */ for(i = 0; i < maxItems - 1; ++i){ for (j = 0; j < cc_items_size - i - 1; ++j){ if (cc_items[j].similarity > cc_items[j + 1].similarity){ struct cc_item tmp = cc_items[j]; cc_items[j] = cc_items[j + 1]; cc_items[j + 1] = tmp; } } } /* print top k items */ n = ((cc_items_size < maxItems) ? cc_items_size : maxItems); for(j = 0; j < n; j++){ i = cc_items_size-j-1; if(cc_items[i].similarity > 0){ print_item(cc_items[i]); } } free(cc_items); return 0; }
void redis_test(void) { unsigned int i; redisReply *r; redisContext *ctx; struct timeval tv; tv.tv_sec = 30; tv.tv_usec = 0; /* 1. 连接Redis服务器 * 带有超时的方式链接Redis服务器, 同时获取与Redis连接的上下文对象. * 该对象将用于其后所有与Redis操作的函数. */ ctx = redisConnectWithTimeout(REDIS_SERVER_IP_ADDR, REDIS_SERVER_PORT, tv); if (ctx->err) { fprintf(stderr, "Connect redis server failed! ip:%s port:%d", REDIS_SERVER_IP_ADDR, REDIS_SERVER_PORT); goto ERROR; } /* 2. 设置KEY-VALUE对 * 需要注意的是, 如果返回的对象是NULL, 则表示客户端和服务器之间出现严重错误, * 必须重新链接. 这里只是举例说明, 简便起见, 后面的命令就不再做这样的判断了. */ const char *command1 = "set stest2 value2"; r = (redisReply *)redisCommand(ctx, command1); if (NULL == r) { fprintf(stderr, "Execute [%s] failed!", command1); goto ERROR; } /* 不同的Redis命令返回的数据类型不同, 在获取之前需要先判断它的实际类型. * 至于各种命令的返回值信息, 可以参考Redis的官方文档, 或者查看该系列博客的前几篇 * 有关Redis各种数据类型的博客.:) * 字符串类型的set命令的返回值的类型是REDIS_REPLY_STATUS, 然后只有当返回信息是"OK" * 时, 才表示该命令执行成功.后面的例子以此类推, 就不再过多赘述了. */ if (REDIS_REPLY_STATUS != r->type || 0 != strcasecmp(r->str, "OK")) { fprintf(stderr, "Execute [%s] failed!\n", command1); freeReplyObject(r); goto ERROR; } printf("Execute [%s] Success!\n", command1); /* 由于后面重复使用该变量, 所以需要提前释放, 否则内存泄漏. */ freeReplyObject(r); /* 3. 获取KEY的VALUE长度 */ const char *command2 = "strlen stest1"; r = (redisReply *)redisCommand(ctx, command2); if (REDIS_REPLY_INTEGER != r->type) { fprintf(stderr, "Execute [%s] failed!\n", command2); freeReplyObject(r); goto ERROR; } printf("Execute [%s] Success! Length:%lld\n", command2, r->integer); freeReplyObject(r); /* 4. 获取KEY的VALUE值 */ const char *command3 = "get stest1"; r = (redisReply *)redisCommand(ctx, command3); if (REDIS_REPLY_STRING != r->type) { fprintf(stderr, "Execute [%s] failed!\n", command3); freeReplyObject(r); goto ERROR; } printf("Execute [%s] Success. Value:%s\n", command3, r->str); freeReplyObject(r); /* 5. 获取KEY的VALUE值 */ const char *command4 = "get stest2"; r = (redisReply *)redisCommand(ctx, command4); /* 这里需要先说明一下, 由于stest2键并不存在, 因此Redis会返回空结果, * 这里只是为了演示. */ if (REDIS_REPLY_NIL == r->type) { printf("Execute [%s] is NIL!\n", command4); } else if (REDIS_REPLY_STRING != r->type) { fprintf(stderr, "Execute [%s] failed!\n", command4); freeReplyObject(r); goto ERROR; } else { printf("Execute [%s] Success! Value:%s\n", command4, r->str); } freeReplyObject(r); /* 6. 获取多个KEY的VALUE值 */ const char *command5 = "mget stest1 stest2"; r = (redisReply *)redisCommand(ctx, command5); /* 不论stest2存在与否, Redis都会给出结果, 只是第二个值为nil. * 由于有多个值返回, 因为返回应答的类型是数组类型. */ if (REDIS_REPLY_ARRAY != r->type) { fprintf(stderr, "Execute [%s] failed!\n", command5); freeReplyObject(r); /* r->elements表示子元素的数量, 不管请求的key是否存在, * 该值都等于请求是键的数量. */ assert(2 == r->elements); goto ERROR; } for (i = 0; i < r->elements; ++i) { redisReply* childReply = r->element[i]; /* 之前已经介绍过, get命令返回的数据类型是string. * 对于不存在key的返回值, 其类型为REDIS_REPLY_NIL. */ if (REDIS_REPLY_STRING == childReply->type) { printf("Value[%d]: %s\n", i, childReply->str); } } printf("Execute [%s] Success!\n", command5); /* 对于每一个子应答, 无需使用者单独释放, 只需释放最外部的redisReply即可. */ freeReplyObject(r); /* 7. 测试异步IO通信 */ printf("Begin to test pipeline.\n"); /* 该命令只是将待发送的命令写入到上下文对象的输出缓冲区中, 直到调用后面的 * redisGetReply命令才会批量将缓冲区中的命令写出到Redis服务器.这样可以 * 有效的减少客户端与服务器之间的同步等候时间, 以及网络IO引起的延迟. * 至于管线的具体性能优势, 可以考虑该系列博客中的管线主题. */ if (REDIS_OK != redisAppendCommand(ctx, command1) || REDIS_OK != redisAppendCommand(ctx, command2) || REDIS_OK != redisAppendCommand(ctx, command3) || REDIS_OK != redisAppendCommand(ctx, command4) || REDIS_OK != redisAppendCommand(ctx, command5)) { fprintf(stderr, "Execute append command failed!\n"); goto ERROR; } /* 对pipeline返回结果的处理方式, 和前面代码的处理方式完全一样, * 这里就不再重复给出了. */ if (REDIS_OK != redisGetReply(ctx, (void **)&r)) { fprintf(stderr, "Execute [%s] with pipeline failed!\n", command1); freeReplyObject(r); goto ERROR; } printf("Execute [%s] with pipeline success.\n", command1); freeReplyObject(r); if (REDIS_OK != redisGetReply(ctx, (void **)&r)) { fprintf(stderr, "Execute [%s] with pipeline failed!\n", command2); freeReplyObject(r); goto ERROR; } printf("Execute [%s] with pipeline success!\n", command2); freeReplyObject(r); if (REDIS_OK != redisGetReply(ctx, (void **)&r)) { fprintf(stderr, "Execute [%s] with pipeline failed!.\n", command3); freeReplyObject(r); goto ERROR; } freeReplyObject(r); printf("Execute [%s] with pipeline success!\n", command3); if (REDIS_OK != redisGetReply(ctx, (void **)&r)) { fprintf(stderr, "Execute [%s] with pipeline failed!\n", command4); freeReplyObject(r); goto ERROR; } freeReplyObject(r); printf("Execute [%s] with pipeline success!\n", command4); if (REDIS_OK != redisGetReply(ctx, (void **)&r)) { fprintf(stderr, "Execute [%s] with pipeline failed!\n", command5); freeReplyObject(r); goto ERROR; } freeReplyObject(r); printf("Execute [%s] with pipeline success!\n", command5); //由于所有通过pipeline提交的命令结果均已为返回, 如果此时继续调用redisGetReply, //将会导致该函数阻塞并挂起当前线程, 直到有新的通过管线提交的命令结果返回. //最后不要忘记在退出前释放当前连接的上下文对象. ERROR: redisFree(ctx); return; }
static void test_throughput(struct config config) { redisContext *c = connect(config); redisReply **replies; int i, num; long long t1, t2; test("Throughput:\n"); for (i = 0; i < 500; i++) freeReplyObject(redisCommand(c,"LPUSH mylist foo")); num = 1000; replies = malloc(sizeof(redisReply*)*num); t1 = usec(); for (i = 0; i < num; i++) { replies[i] = redisCommand(c,"PING"); assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); free(replies); printf("\t(%dx PING: %.3fs)\n", num, (t2-t1)/1000000.0); replies = malloc(sizeof(redisReply*)*num); t1 = usec(); for (i = 0; i < num; i++) { replies[i] = redisCommand(c,"LRANGE mylist 0 499"); assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); assert(replies[i] != NULL && replies[i]->elements == 500); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); free(replies); printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0); num = 10000; replies = malloc(sizeof(redisReply*)*num); for (i = 0; i < num; i++) redisAppendCommand(c,"PING"); t1 = usec(); for (i = 0; i < num; i++) { assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_STATUS); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); free(replies); printf("\t(%dx PING (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); replies = malloc(sizeof(redisReply*)*num); for (i = 0; i < num; i++) redisAppendCommand(c,"LRANGE mylist 0 499"); t1 = usec(); for (i = 0; i < num; i++) { assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK); assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_ARRAY); assert(replies[i] != NULL && replies[i]->elements == 500); } t2 = usec(); for (i = 0; i < num; i++) freeReplyObject(replies[i]); free(replies); printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0); disconnect(c, 0); }
int main() { int i; char *str; int content_length; char buffer[BUFFER_SIZE + 1]; /* Default values for Redis connection information. */ char redis_server[HOSTNAME_LEN + 1] = "localhost"; int redis_port = 6379; char redis_key[KEY_LEN + 1] = "yamsetl"; redisContext *c; redisReply *reply; str = getenv("REDIS_SERVER"); if (str != NULL) strncpy(redis_server, str, HOSTNAME_LEN); str = getenv("REDIS_PORT"); if (str != NULL) redis_port = atoi(str); str = getenv("REDIS_KEY"); if (str != NULL) strncpy(redis_key, str, KEY_LEN); /* * Open a connection to Redis once the FastCGI service starts for * the life of the service. */ c = redisConnect(redis_server, redis_port); if (c->err) { printf("yams-etl-fastcgi error: %s\n", c->errstr); return 1; } while (FCGI_Accept() >= 0) { char *request_method; request_method = getenv("REQUEST_METHOD"); if (request_method == NULL) continue; /* Create a minimal HTTP response. */ printf("\r\n"); if (strcmp(request_method, "POST") == 0) { /* Get the POST data. */ str = getenv("CONTENT_LENGTH"); if (str != NULL) content_length = atoi(str); else content_length = -1; i = 0; while (i < content_length && i < BUFFER_SIZE) buffer[i++] = getchar(); buffer[i] = '\0'; /* Push the POST data to Redis. */ reply = redisCommand(c, "LPUSH %s \"%s\"", redis_key, buffer); /* TODO: Handle failed LPUSH. */ freeReplyObject(reply); } } return 0; }
/** Locate a cache entry in redis * * @copydetails cache_entry_find_t */ static cache_status_t cache_entry_find(rlm_cache_entry_t **out, UNUSED rlm_cache_config_t const *config, void *driver_inst, REQUEST *request, UNUSED void *handle, uint8_t const *key, size_t key_len) { rlm_cache_redis_t *driver = driver_inst; size_t i; fr_redis_cluster_state_t state; fr_redis_conn_t *conn; fr_redis_rcode_t status; redisReply *reply = NULL; int s_ret; vp_map_t *head = NULL, **last = &head; #ifdef HAVE_TALLOC_POOLED_OBJECT size_t pool_size = 0; #endif rlm_cache_entry_t *c; for (s_ret = fr_redis_cluster_state_init(&state, &conn, driver->cluster, request, key, key_len, false); s_ret == REDIS_RCODE_TRY_AGAIN; /* Continue */ s_ret = fr_redis_cluster_state_next(&state, &conn, driver->cluster, request, status, &reply)) { /* * Grab all the data for this hash, should return an array * of alternating keys/values which we then convert into maps. */ if (RDEBUG_ENABLED3) { char *p; p = fr_asprint(NULL, (char const *)key, key_len, '"'); RDEBUG3("LRANGE %s 0 -1", key); talloc_free(p); } reply = redisCommand(conn->handle, "LRANGE %b 0 -1", key, key_len); status = fr_redis_command_status(conn, reply); } if (s_ret != REDIS_RCODE_SUCCESS) { RERROR("Failed retrieving entry"); fr_redis_reply_free(reply); return CACHE_ERROR; } rad_assert(reply); /* clang scan */ if (reply->type != REDIS_REPLY_ARRAY) { REDEBUG("Bad result type, expected array, got %s", fr_int2str(redis_reply_types, reply->type, "<UNKNOWN>")); fr_redis_reply_free(reply); return CACHE_ERROR; } RDEBUG3("Entry contains %zu elements", reply->elements); if (reply->elements == 0) { fr_redis_reply_free(reply); return CACHE_MISS; } if (reply->elements % 3) { REDEBUG("Invalid number of reply elements (%zu). " "Reply must contain triplets of keys operators and values", reply->elements); fr_redis_reply_free(reply); return CACHE_ERROR; } #ifdef HAVE_TALLOC_POOLED_OBJECT /* * We can get a pretty good idea of the required size of the pool */ for (i = 0; i < reply->elements; i += 3) { pool_size += sizeof(vp_map_t) + (sizeof(vp_tmpl_t) * 2); if (reply->element[i]->type == REDIS_REPLY_STRING) pool_size += reply->element[i]->len + 1; } /* * reply->elements gives us the number of chunks, as the maps are triplets, and there * are three chunks per map */ c = talloc_pooled_object(NULL, rlm_cache_entry_t, reply->elements, pool_size); memset(&pool, 0, sizeof(rlm_cache_entry_t)); #else c = talloc_zero(NULL, rlm_cache_entry_t); #endif /* * Convert the key/value pairs back into maps */ for (i = 0; i < reply->elements; i += 3) { if (fr_redis_reply_to_map(c, last, request, reply->element[i], reply->element[i + 1], reply->element[i + 2]) < 0) { talloc_free(c); fr_redis_reply_free(reply); return CACHE_ERROR; } last = &(*last)->next; } fr_redis_reply_free(reply); /* * Pull out the cache created date */ if ((head->lhs->tmpl_da->vendor == 0) && (head->lhs->tmpl_da->attr == PW_CACHE_CREATED)) { vp_map_t *map; c->created = head->rhs->tmpl_data_value.date; map = head; head = head->next; talloc_free(map); } /* * Pull out the cache expires date */ if ((head->lhs->tmpl_da->vendor == 0) && (head->lhs->tmpl_da->attr == PW_CACHE_EXPIRES)) { vp_map_t *map; c->expires = head->rhs->tmpl_data_value.date; map = head; head = head->next; talloc_free(map); } c->key = talloc_memdup(c, key, key_len); c->key_len = key_len; c->maps = head; *out = c; return CACHE_OK; }
int Grab::getGrabNum(const string& user_id, string& num, int32_t is_pre) { extern string IP; int res; string query_sql; //DuokooMysql mysql; DuokooMysql mysql("grab_mysql"); if(!mysql.startTransaction()){ return -5; } //get num from mysql //comment by zhengxie 2013.10.22 /*query_sql="SELECT num FROM `MCP`.`mcp_content_grab_num` WHERE `is_occupy` = 0 AND `grab_id` = " + toString(_id) + " limit 0, 1";*/ //UB_LOG_DEBUG("query_sql:[%s]", query_sql.c_str()); //res=mysql.query(query_sql); //if(res<0){ //UB_LOG_FATAL( "query sql[%s] failed, [%s], [%s:%d]", query_sql.c_str(), mysql.getErrDes().c_str(), __FILE__, __LINE__ ); //mysql.rollback(); //return -5; //}else if(res==0){ //UB_LOG_FATAL( "query sql[%s] have no record, [%s:%d]", query_sql.c_str(), __FILE__, __LINE__ ); //mysql.rollback(); //return -3; //} /*num=mysql.getResult(0,0);*/ /* 2013.10.22 add by zhengxie get num from mysql => get num from redis start */ redisContext *c; uint32_t send_amount(0); c=redisConnPool::getInstance()->getConnection(); if(c==NULL) { UB_LOG_FATAL( "get redis connection failed, [%s:%d]", __FILE__, __LINE__ ); return -5; } redisReply *reply; /* 2013.12.03 add by zhengxie add lock */ string thread_id = DuokooTools::toString(CommonInterface::get_thread_id()); string random = DuokooTools::toString(getRandomNum(10000000)); string key = "grab_and_user_id:" + DuokooTools::toString(_id) + "," + user_id; string value = IP + "," + thread_id + "," + random; redisCommand(c, "SETNX %s %s", key.c_str(), value.c_str()); LOGD( "[zx]get_value key:%s ", key.c_str() ); reply = (redisReply*)redisCommand( c, "GET %s", key.c_str() ); redisConnPool::getInstance()->releaseConnection(c); if(reply!=NULL) { if(reply->type!=REDIS_REPLY_ERROR) { if(reply->type!=REDIS_REPLY_NIL) { string temp_value = reply->str; freeReplyObject(reply); reply = NULL; if(strcmp(temp_value.c_str(), value.c_str())) { LOGA( "[zx] shit, bad user[%s] ", user_id.c_str() ); return -3;//同一个用户重复抢号 } } else { freeReplyObject(reply); reply = NULL; return -3; } } } else { LOGA( "[zx] key not set[%s] ", key.c_str() ); return -5; } /* 2013.12.03 add by zhengxie add lock */ c=redisConnPool::getInstance()->getConnection(); if(c==NULL) { UB_LOG_FATAL( "get redis connection failed, [%s:%d]", __FILE__, __LINE__ ); return -5; } redisCommand(c, "EXPIRE %s %ld", key.c_str(), 10*24*60*60); //LOGD( "[zx]SPOP grab_id:%d ", _id ); reply = (redisReply*)redisCommand( c, "SPOP grab_id:%d", _id ); redisConnPool::getInstance()->releaseConnection(c); if(reply!=NULL) { if(reply->type!=REDIS_REPLY_ERROR) { if(reply->type!=REDIS_REPLY_NIL) { LOGA( "grab_id:[%d], user_id:[%s], grab_num:[%s]", _id, user_id.c_str(), reply->str ); num=reply->str; freeReplyObject(reply); reply = NULL; } else { LOGD( "[zx] has no grab_nums grab_id[%d] ", _id ); freeReplyObject(reply); reply = NULL; return -3; } } } else { LOGD( "[zx] not exist grab_id[%d] ", _id ); return -5; } /* 2013.10.22 add by zhengxie get num from mysql => get num from redis end */ //update num query_sql="UPDATE `MCP`.`mcp_content_grab_num` SET `is_occupy` = "+ toString(is_pre) +" WHERE num = '" + num + "' "; UB_LOG_DEBUG("query_sql:[%s]", query_sql.c_str()); res=mysql.query(query_sql); if(res<0){ UB_LOG_FATAL( "query sql[%s] failed, [%s], [%s:%d]", query_sql.c_str(), mysql.getErrDes().c_str(), __FILE__, __LINE__ ); mysql.rollback(); return -5; } //insert user_num query_sql="INSERT INTO `MCP`.`mcp_content_user_grab`( `id`, `grab_id`, `user_id`, `grab_time`, `use_time`, `num` )" "VALUES( NULL, '"+toString(_id)+"', '"+user_id+"', '"+NOW()+"', '0', '"+num+"' ) "; UB_LOG_DEBUG("query_sql:[%s]", query_sql.c_str()); res=mysql.query(query_sql); if(res<0){ UB_LOG_FATAL( "query sql[%s] failed, [%s], [%s:%d]", query_sql.c_str(), mysql.getErrDes().c_str(), __FILE__, __LINE__ ); mysql.rollback(); return -5; } return mysql.commit()?0:-5; }
/* 处理模块 */ void httpsqs_handler(struct evhttp_request *req, void *arg) { struct evbuffer *buf; buf = evbuffer_new(); /* 分析URL参数 */ char *decode_uri = strdup((char*) evhttp_request_uri(req)); struct evkeyvalq httpsqs_http_query; evhttp_parse_query(decode_uri, &httpsqs_http_query); free(decode_uri); /* 接收GET表单参数 */ const char *httpsqs_input_name = evhttp_find_header (&httpsqs_http_query, "name"); /* 队列名称 */ const char *httpsqs_input_charset = evhttp_find_header (&httpsqs_http_query, "charset"); /* 操作类别 */ const char *httpsqs_input_opt = evhttp_find_header (&httpsqs_http_query, "opt"); /* 操作类别 */ const char *httpsqs_input_data = evhttp_find_header (&httpsqs_http_query, "data"); /* 操作类别 */ /* 返回给用户的Header头信息 */ if (httpsqs_input_charset != NULL && strlen(httpsqs_input_charset) <= 40) { char *content_type = (char *)malloc(64); memset(content_type, '\0', 64); sprintf(content_type, "text/plain; charset=%s", httpsqs_input_charset); evhttp_add_header(req->output_headers, "Content-Type", content_type); free(content_type); } else { evhttp_add_header(req->output_headers, "Content-Type", "text/plain"); } evhttp_add_header(req->output_headers, "Connection", "keep-alive"); evhttp_add_header(req->output_headers, "Cache-Control", "no-cache"); /*参数是否存在判断 */ if (httpsqs_input_name != NULL && httpsqs_input_opt != NULL && strlen(httpsqs_input_name) <= 256) { /* 入队列 */ if (strcmp(httpsqs_input_opt, "put") == 0) { /* 优先接收POST正文信息 */ int buffer_data_len; buffer_data_len = EVBUFFER_LENGTH(req->input_buffer); char* httpsqs_input_postbuffer = NULL; char* buffer_data = NULL; if (buffer_data_len <=0 && httpsqs_input_data == NULL) { evbuffer_add_printf(buf, "%s", "HTTPSQS_PUT_ERROR"); } else { if (buffer_data_len > 0) { buffer_data = (char *)malloc(buffer_data_len + 1); memset(buffer_data, '\0', buffer_data_len + 1); memcpy (buffer_data, EVBUFFER_DATA(req->input_buffer), buffer_data_len); httpsqs_input_postbuffer = urldecode(buffer_data); /* 如果POST正文无内容,则取URL中data参数的值 */ } else if (httpsqs_input_data != NULL) { buffer_data_len = strlen(httpsqs_input_data); buffer_data = (char *)malloc(buffer_data_len + 1); memset(buffer_data, '\0', buffer_data_len + 1); memcpy (buffer_data, httpsqs_input_data, buffer_data_len); httpsqs_input_postbuffer = urldecode(buffer_data); } redisReply* reply = (redisReply*)redisCommand(redis_client, "RPUSH %s %s", httpsqs_input_name, httpsqs_input_postbuffer); if (reply == NULL) { fprintf(stderr, "Put queue message failed:%s [error]:%d", httpsqs_input_name, reply->type); evbuffer_add_printf(buf, "%s", "HTTPSQS_PUT_ERROR"); } else { evbuffer_add_printf(buf, "%s", "HTTPSQS_PUT_OK"); freeReplyObject(reply); } if (httpsqs_input_postbuffer != NULL) free(httpsqs_input_postbuffer); if (buffer_data != NULL) free(buffer_data); } } else if (strcmp(httpsqs_input_opt, "get") == 0) { /* 出队列 */ redisReply* reply = (redisReply*)redisCommand(redis_client, "LPOP %s", httpsqs_input_name); if (reply == NULL) { evbuffer_add_printf(buf, "%s", "HTTPSQS_GET_ERROR"); } else if (reply->type == REDIS_REPLY_NIL){ evbuffer_add_printf(buf, "%s", "HTTPSQS_GET_END"); freeReplyObject(reply); } else { evbuffer_add_printf(buf, "%s", reply->str); freeReplyObject(reply); } } else if (strcmp(httpsqs_input_opt, "status") == 0) { /* 查看队列状态(普通浏览方式) */ evbuffer_add_printf(buf, "#TODO"); } else if (strcmp(httpsqs_input_opt, "status_json") == 0) { /* 查看队列状态(JSON方式,方便客服端程序处理) */ evbuffer_add_printf(buf, "#TODO"); } else if (strcmp(httpsqs_input_opt, "view") == 0 ) { /* 查看单条队列内容 */ evbuffer_add_printf(buf, "#TODO"); } else { /* 命令错误 */ evbuffer_add_printf(buf, "%s", "HTTPSQS_ERROR"); } } else { /* 命令错误 */ evbuffer_add_printf(buf, "%s", "HTTPSQS_ERROR"); } /* 输出内容给客户端 */ evhttp_send_reply(req, HTTP_OK, "OK", buf); /* 内存释放 */ evhttp_clear_headers(&httpsqs_http_query); evbuffer_free(buf); }
static bool startup( disruptor* d ) { bool wasCreated = false; redisContext* r; redisReply* reply; /* validate inputs. */ { if ( !isStringValid( d->address, 1, MAX_ADDRESS_LENGTH ) ) { handleError( d, "invalid length for string '%s'", d->address ); return false; } if ( !isStringValid( d->username, 1, MAX_USERNAME_LENGTH ) ) { handleError( d, "invalid length for string '%s'", d->username ); return false; } } /* connect to redis. */ r = d->redis = connectToRedis(); if ( !r ) { handleError( d, "could not connect to redis" ); return false; } /* determine a mapping for this connection. */ { int id = -1; /* try to fetch an existing mapping. */ { reply = redisCommand( r, "GET disruptor:%s:connections:%s:id", d->address, d->username ); if ( reply->type == REDIS_REPLY_STRING ) { id = atoi( reply->str ); } freeReplyObject( reply ); } /* if no mapping exists, then assign a new one. */ if ( id < 0 ) { { reply = redisCommand( r, "INCR disruptor:%s:connectionsCount", d->address ); if ( reply->type == REDIS_REPLY_INTEGER ) id = ( reply->integer - 1 ); freeReplyObject( reply ); } assert( id >= 0 ); if ( id < 0 ) { handleError( d, "could not determine mapping for username '%s'", d->username ); return false; } wasCreated = true; { reply = redisCommand( r, "SET disruptor:%s:connections:%s:id %d", d->address, d->username, id ); freeReplyObject( reply ); } { reply = redisCommand( r, "SET disruptor:%s:%d:username %s", d->address, id, d->username ); freeReplyObject( reply ); } } d->id = id; } /* determine the connection count. */ { d->connectionsCount = 0; reply = redisCommand( r, "GET disruptor:%s:connectionsCount", d->address, d->username ); if ( reply->type == REDIS_REPLY_STRING ) d->connectionsCount = atoi( reply->str ); freeReplyObject( reply ); if ( d->connectionsCount <= 0 ) { handleError( d, "could not determine the connection count." ); return false; } } handleInfo( d, "id=%d total=%d", d->id, d->connectionsCount ); /* open the shared header. */ { d->shHeader = shmemOpen( sizeof(sharedHeader), SHMEM_DEFAULT, "disruptor:%s", d->address ); d->header = shmemGetPtr( d->shHeader ); } /* open the shared ringbuffer. */ { d->shRingbuffer = shmemOpen( sizeof(sharedRingbuffer), SHMEM_DEFAULT, "disruptor:%s:rb", d->address ); d->ringbuffer = shmemGetPtr( d->shRingbuffer ); } { int i; /* create the shared memory sendBuffer. */ if ( wasCreated ) { shmem* s; handleInfo( d, "creating %d", d->id ); s = shmemOpen( d->sendBufferSize, SHMEM_MUST_CREATE, "disruptor:%s:%d", d->address, d->id ); shmemClose( s ); } /* map each connection. */ for ( i = 0; i < d->connectionsCount; ++i ) { if ( !mapClient( d, i ) ) { handleError( d, "could not map client %d", i ); return false; } } } return true; }
//有多少个词条就开多少个线程来模拟分叉树算法,选出词条最多的一个或几个作为分词结果 int _tree_cut_words(struct TREE_CUT_WORDS_DATA *parent_cut_words_data) { english_word_cut((*parent_cut_words_data).cut_word_result, &((*parent_cut_words_data).remainder_words), (*parent_cut_words_data).words_weight); //取出第一个汉子,查询redis词条,for循环生产不同的父级分词结果,然后传给新建的子进程,进入递归 char *first_chinese_word; first_chinese_word = (char *) malloc(chinese_char_byte); memset(first_chinese_word, 0, chinese_char_byte); if (!first_chinese_word) { //todo.每一个可能的错误都要做处理或日志记录.not only malloc printf("Not Enough Memory!/n"); } strncpy(first_chinese_word, parent_cut_words_data->remainder_words, chinese_word_byte); strcat(first_chinese_word, "\0"); char *get_word_item_cmd = join_char(redis_get_common, first_chinese_word); //用完释放内存 free(first_chinese_word); redisContext *redis_connect; get_redis_connect(&redis_connect); redisReply *redis_reply = redisCommand(redis_connect, get_word_item_cmd); char *match_words_json_str = redis_reply->str; free(get_word_item_cmd); cJSON *match_words_json = cJSON_Parse(match_words_json_str); //是否已经到最后一个词 bool NEED_not_match_word_end_cut; //有多少词条是否包含在搜索词里 int8_t match_words_item_number = 0; //判断是否查找到redis词条 if (redis_reply->type == REDIS_REPLY_STRING) { //pullwords_result_number要先计算好有多少种结果。 for (int tree_arg_index = 0; tree_arg_index < cJSON_GetArraySize(match_words_json); tree_arg_index++) { cJSON *subitem = cJSON_GetArrayItem(match_words_json, tree_arg_index); //判断词条是否包含在搜索词里 if (strstr(parent_cut_words_data->remainder_words, subitem->valuestring) != NULL) { match_words_item_number++; } }; } else { NEED_not_match_word_end_cut = false; } if (match_words_item_number == 0) { NEED_not_match_word_end_cut = true; } if (NEED_not_match_word_end_cut == false) { int8_t add_result_number = 0; //pullwords_result_number要做原子操作,递增,支持并发 add_result_number = match_words_item_number - 1; __sync_fetch_and_add((*parent_cut_words_data).pullwords_result_number, add_result_number); for (int tree_arg_index = 0; tree_arg_index < cJSON_GetArraySize(match_words_json); tree_arg_index++) { cJSON *subitem = cJSON_GetArrayItem(match_words_json, tree_arg_index); //判断词条是否包含在搜索词里,如果在,进入树分词算法 if (strstr(parent_cut_words_data->remainder_words, subitem->valuestring) != NULL) { //复制一份分词结果,生出父级分词结果 struct TREE_CUT_WORDS_DATA *tree_cut_words_data = (struct TREE_CUT_WORDS_DATA *) malloc( sizeof(struct TREE_CUT_WORDS_DATA)); memset(tree_cut_words_data, 0, sizeof(struct TREE_CUT_WORDS_DATA)); init_tree_cut_words_data(tree_cut_words_data); strcpy(tree_cut_words_data->cut_word_result, parent_cut_words_data->cut_word_result); strcpy(tree_cut_words_data->remainder_words, parent_cut_words_data->remainder_words); *tree_cut_words_data->words_weight = *(parent_cut_words_data->words_weight); //todo 把pullwords主线程的data封装成一个指针,减少指针创建,. tree_cut_words_data->pullwords_result_queue = parent_cut_words_data->pullwords_result_queue; tree_cut_words_data->pullwords_result_queue_write_lock = parent_cut_words_data->pullwords_result_queue_write_lock; tree_cut_words_data->pullwords_cond = parent_cut_words_data->pullwords_cond; (*tree_cut_words_data).pullwords_result_number = (*parent_cut_words_data).pullwords_result_number; (*tree_cut_words_data).pullwords_result_finish_number = (*parent_cut_words_data).pullwords_result_finish_number; chinese_word_cut(tree_cut_words_data->cut_word_result, &(tree_cut_words_data->remainder_words), tree_cut_words_data->words_weight, subitem->valuestring); //还有词没分完,进入递归分词 if (strlen(tree_cut_words_data->remainder_words) > 0) { pthread_t pthread_id; int pthread_create_result; pthread_create_result = pthread_create(&pthread_id, NULL, (void *) _tree_cut_words, tree_cut_words_data); if (pthread_create_result != 0) { //todo,deal the error,. printf("Create pthread error!\n"); } } else { //创建线程最终分词结果,写入主线程队列 struct TREE_CUT_WORDS_RESULT *last_tree_cut_words_result = (struct TREE_CUT_WORDS_RESULT *) malloc( sizeof(struct TREE_CUT_WORDS_RESULT)); memset(last_tree_cut_words_result, 0, sizeof(struct TREE_CUT_WORDS_RESULT)); strcpy(last_tree_cut_words_result->pullwords_result, tree_cut_words_data->cut_word_result); last_tree_cut_words_result->words_weight = *(tree_cut_words_data->words_weight); //分词结束,加锁,写入分词结果到主线程的分词队列 pthread_mutex_lock(tree_cut_words_data->pullwords_result_queue_write_lock); EnQueue((*tree_cut_words_data).pullwords_result_queue, last_tree_cut_words_result); *((*parent_cut_words_data).pullwords_result_finish_number) = (*((*parent_cut_words_data).pullwords_result_finish_number)) + 1; //加锁比较pullwords_result_finish_number跟pullwords_result_number,如果全部作业完成,通知主进程 if (*((*parent_cut_words_data).pullwords_result_finish_number) == *((*parent_cut_words_data).pullwords_result_number)) { pthread_cond_signal((*parent_cut_words_data).pullwords_cond); } pthread_mutex_unlock(tree_cut_words_data->pullwords_result_queue_write_lock); } } } } else { //首汉子没有匹配到字典词条 OR 没有查找到redis词条,选取剩下的字作为一个半词 not_match_word_end_cut(parent_cut_words_data->cut_word_result, &(parent_cut_words_data->remainder_words), parent_cut_words_data->words_weight); //创建线程最终分词结果,写入主线程队列 struct TREE_CUT_WORDS_RESULT *last_tree_cut_words_result = (struct TREE_CUT_WORDS_RESULT *) malloc( sizeof(struct TREE_CUT_WORDS_RESULT)); memset(last_tree_cut_words_result, 0, sizeof(struct TREE_CUT_WORDS_RESULT)); strcpy(last_tree_cut_words_result->pullwords_result, parent_cut_words_data->cut_word_result); last_tree_cut_words_result->words_weight = *(parent_cut_words_data->words_weight); //分词结束,加锁,写入分词结果到主线程的分词队列 pthread_mutex_lock(parent_cut_words_data->pullwords_result_queue_write_lock); EnQueue((*parent_cut_words_data).pullwords_result_queue, last_tree_cut_words_result); *((*parent_cut_words_data).pullwords_result_finish_number) = (*((*parent_cut_words_data).pullwords_result_finish_number)) + 1; //加锁比较pullwords_result_finish_number跟pullwords_result_number,如果全部作业完成,通知主进程 if (*((*parent_cut_words_data).pullwords_result_finish_number) == *((*parent_cut_words_data).pullwords_result_number)) { pthread_cond_signal((*parent_cut_words_data).pullwords_cond); } pthread_mutex_unlock(parent_cut_words_data->pullwords_result_queue_write_lock); } free(parent_cut_words_data->cut_word_result); free(parent_cut_words_data->words_weight); free(parent_cut_words_data->origin_remainder_words); free(parent_cut_words_data); return 0; }
void set(std::string key, std::string value) { redisCommand(this->_connect, "SET %s %s", key.c_str(), value.c_str()); }
int main(int argc, char *argv[], char *env[]) { int c; char *redis_server = "127.0.0.1"; int redis_port = 6379; char * redis_queue = "apple_apn"; bool deamon_mode = false; int pid, worker_pid, worker_pid_wait; redisContext *redis; redisReply *reply; cJSON *json; char *deviceToken, *message, *caption; int badge; /* process arguments */ while ((c = getopt(argc, argv, "s:p:q:c:t:dh")) != -1) { switch (c) { case 's': redis_server = strdup(optarg); //malloc + strcpy break; case 'p': redis_port = atoi(optarg); break; case 'q': redis_queue = strdup(optarg); break; case 'd': deamon_mode = true; break; case 'h': default: show_help(); return 1; } } //以守护进程运行 if(deamon_mode == true) { /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(0); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(1); } } /* 派生子进程(工作进程) */ worker_pid = fork(); //如果是父进程 if(worker_pid > 0) { /* 处理父进程接收到的kill信号 */ /* 忽略Broken Pipe信号 */ signal(SIGPIPE, SIG_IGN); /* 处理kill信号 */ signal (SIGINT, kill_signal_master); signal (SIGKILL, kill_signal_master); signal (SIGQUIT, kill_signal_master); signal (SIGTERM, kill_signal_master); signal (SIGHUP, kill_signal_master); /* 处理段错误信号 */ signal(SIGSEGV, kill_signal_master); /* 如果子进程终止,则重新派生新的子进程 */ while (1) { worker_pid_wait = wait(NULL); if (worker_pid_wait < 0) { continue; } usleep(100000); worker_pid = fork(); /*成功生成子进程*/ if (worker_pid == 0) { break; } } } /* ---------------子进程内容------------------- */ /* 忽略Broken Pipe信号 */ signal(SIGPIPE, SIG_IGN); /* 处理kill信号 */ signal (SIGINT, kill_signal_worker); signal (SIGKILL, kill_signal_worker); signal (SIGQUIT, kill_signal_worker); signal (SIGTERM, kill_signal_worker); signal (SIGHUP, kill_signal_worker); /* 处理段错误信号 */ signal(SIGSEGV, kill_signal_worker); /* working */ struct timeval timeout = { 1, 500000 }; // 1.5 seconds redis = redisConnectWithTimeout(redis_server, redis_port, timeout); reply = redisCommand(redis, "SUBSCRIBE apple_apn"); freeReplyObject(reply); while(redisGetReply(redis, (void**)&reply) == REDIS_OK) { printf("content:%s\n", reply->element[2]->str); json = cJSON_Parse(reply->element[2]->str); if (!json) { printf("Error before: [%s]\n",cJSON_GetErrorPtr()); continue; } deviceToken = cJSON_GetObjectItem(json,"deviceToken")->valuestring; message = cJSON_GetObjectItem(json,"message")->valuestring; caption = cJSON_GetObjectItem(json,"caption")->valuestring; badge = cJSON_GetObjectItem(json,"badge")->valueint; if(deviceToken == NULL || message == NULL || caption == NULL || badge == 0 || strlen(deviceToken) != 64 ) { printf("send params error:<deviceToken = %s ,message = %s ,caption = %s ,badge = %d>\n", deviceToken, message, caption, badge); continue; } Payload *payload = (Payload*)malloc(sizeof(Payload)); init_payload(payload); //deviceToken = "83d4071e8c9a0afff108c2fa431a569cd71298d863da2462a555994ca3aac53a"; payload->message = message; payload->badgeNumber = badge; payload->actionKeyCaption = caption; payload->dictKey[0] = NULL; payload->dictValue[0] = NULL; printf("Sending APN to Device with UDID: %s\n", deviceToken); send_remote_notification(deviceToken, payload); } while(1) { sleep(2); /* 出错的话尝试重连 */ if (redis->err) { redis = redisConnectWithTimeout(redis_server, redis_port, timeout); printf("redis Server[%s] connection error: %s\n", redis_server, redis->errstr); continue; kill_signal_master(SIGQUIT); }else{ exit(0); } //process(redis, redis_queue, loop_time); } }
static int LogFileWriteRedis(LogFileCtx *file_ctx, const char *string, size_t string_len) { if (file_ctx->redis == NULL) { SCConfLogReopenRedis(file_ctx); if (file_ctx->redis == NULL) { return -1; } else { SCLogInfo("Reconnected to redis server"); } } /* TODO go async here ? */ if (file_ctx->redis_setup.batch_size) { redisAppendCommand(file_ctx->redis, "%s %s %s", file_ctx->redis_setup.command, file_ctx->redis_setup.key, string); if (file_ctx->redis_setup.batch_count == file_ctx->redis_setup.batch_size) { redisReply *reply; int i; file_ctx->redis_setup.batch_count = 0; for (i = 0; i <= file_ctx->redis_setup.batch_size; i++) { if (redisGetReply(file_ctx->redis, (void **)&reply) == REDIS_OK) { freeReplyObject(reply); } else { if (file_ctx->redis->err) { SCLogInfo("Error when fetching reply: %s (%d)", file_ctx->redis->errstr, file_ctx->redis->err); } switch (file_ctx->redis->err) { case REDIS_ERR_EOF: case REDIS_ERR_IO: SCLogInfo("Reopening connection to redis server"); SCConfLogReopenRedis(file_ctx); if (file_ctx->redis) { SCLogInfo("Reconnected to redis server"); return 0; } else { SCLogInfo("Unable to reconnect to redis server"); return 0; } break; default: SCLogWarning(SC_ERR_INVALID_VALUE, "Unsupported error code %d", file_ctx->redis->err); return 0; } } } } else { file_ctx->redis_setup.batch_count++; } } else { redisReply *reply = redisCommand(file_ctx->redis, "%s %s %b", file_ctx->redis_setup.command, file_ctx->redis_setup.key, string, string_len); /* We may lose the reply if disconnection happens! */ if (reply) { switch (reply->type) { case REDIS_REPLY_ERROR: SCLogWarning(SC_ERR_SOCKET, "Redis error: %s", reply->str); SCConfLogReopenRedis(file_ctx); break; case REDIS_REPLY_INTEGER: SCLogDebug("Redis integer %lld", reply->integer); break; default: SCLogError(SC_ERR_INVALID_VALUE, "Redis default triggered with %d", reply->type); SCConfLogReopenRedis(file_ctx); break; } freeReplyObject(reply); } else { SCConfLogReopenRedis(file_ctx); } } return 0; }
void generatePuzzle() { printf("Generating Puzzle:\n"); size_t keyCount = 0; size_t targetCount = 0; int i = 0; // Get current image count in database redisReply *getReply = redisCommand(Context, "SCARD %s", GRP_TARGET_NAME); keyCount = getReply->integer; freeReplyObject(getReply); // Check if there is right amount of images if (keyCount >= MIN_IMAGE_TYPES) { /* * Get background */ // Get background size redisReply *backgroundSize = redisCommand(Context, "SCARD %s", GRP_BACKGROUND_NAME); char backgroundNumber[4]; char backgroundFileName[64]; int randomBackgroundNumber = 1; targetCount = backgroundSize->integer; if (randomBackgroundNumber != (int)targetCount) { randomBackgroundNumber = generateRandomNumber(1, (int)backgroundSize->integer); } snprintf(backgroundNumber, 4, "%d", randomBackgroundNumber); strcpy(backgroundFileName, ""); strcat(backgroundFileName, BackgroundDIR); strcat(backgroundFileName, "/"); strcat(backgroundFileName, BackgroundDIR); strcat(backgroundFileName, backgroundNumber); strcat(backgroundFileName, ".jpg"); printf("\nPicked %s%s as background\n", BackgroundDIR, backgroundNumber); freeReplyObject(backgroundSize); // Get a background image gdImagePtr background = loadImage(backgroundFileName, ".jpg"); if (background == NULL) { // Exit out printf("Error opening background image\n"); return; } int randomArray[MIN_IMAGE_TYPES] = {0, 0, 0, 0, 0}; generateRandomTargetGroups(1, MIN_IMAGE_TYPES, randomArray); redisReply *targetList = redisCommand(Context, "SMEMBERS %s", GRP_TARGET_NAME); printf("\nPicked targets Below:\n"); for (i = 0; i < MIN_IMAGE_TYPES; i++) { // Check if there is min amount of images redisReply *minImages = redisCommand(Context, "SCARD %s", targetList->element[i]->str); if (minImages->integer >= MIN_EACH_TYPE) { redisReply *currentTarget = redisCommand(Context, "SMEMBERS %s", targetList->element[i]->str); int randomTargetArray[MIN_EACH_TYPE] = {0, 0, 0}; generateRandomTargetGroups(1, MIN_EACH_TYPE, randomTargetArray); printf("\nFor %s we are using:\n", targetList->element[i]->str); int j = 0; for (j = 0; j < MIN_EACH_TYPE; j++) { /* * Get Each Target */ char targetFileName[64]; strcpy(targetFileName, ""); strcat(targetFileName, TargetDIR); strcat(targetFileName, "/"); strcat(targetFileName, currentTarget->element[j]->str); strcat(targetFileName, ".png"); printf("\t%s\n", currentTarget->element[j]->str); // Get a background image gdImagePtr targetImage = loadImage(targetFileName, ".png"); int top = generateRandomNumber(100, (background->sx - 100)); int bottom = top + targetImage->sy; int left = generateRandomNumber(100, (background->sy - 100)); int right = left + targetImage->sx; // Write out info to file FILE *coords = fopen("puzzle.txt", "a"); fprintf(coords, "%d, %d, %d, %d\n", top, bottom, left, right); fclose(coords); gdImageCopy(background, targetImage, top, left, 0, 0, 100, targetImage->sy); gdImageDestroy(targetImage); } // Free freeReplyObject(currentTarget); } else { printf("Add %lld more target groups to %s\n", (MIN_EACH_TYPE - minImages->integer), targetList->element[0]->str); break; } // Get random image category for user to chose redisReply *targetListCount = redisCommand(Context, "SCARD %s", GRP_TARGET_NAME); int randomTargetGroup = generateRandomNumber(1, (int)targetListCount->integer); freeReplyObject(targetListCount); redisReply *currentTarget = redisCommand(Context, "SMEMBERS %s", targetList->element[randomTargetGroup-1]->str); char *fileName = currentTarget->element[0]->str; char fileNameFinal[64]; strcpy(fileNameFinal, ""); strcat(fileNameFinal, TargetDIR); strcat(fileNameFinal, "/"); strcat(fileNameFinal, fileName); strcat(fileNameFinal, ".png"); // Get image of random target gdImagePtr lookingFor = loadImage(fileNameFinal, ".png"); // Make HTML page generateHTML(background, lookingFor); freeReplyObject(currentTarget); freeReplyObject(minImages); } gdImageDestroy(background); freeReplyObject(targetList); } else { printf("Add %lu more target groups\n", (MIN_IMAGE_TYPES - keyCount)); } }
void control_init() { redisContext *redis; redisReply *reply; int i, rc; int push_default = 1; rc = pthread_rwlock_init(¶ms_rwlock, NULL); handle_errmsg("pthread_rwlock_init()\n", rc); param_val_curr = (double *) safe_malloc("param_val_curr", num_ctrl_cmd_param() * sizeof(double)); if (cmd_change == NULL) { cmd_change = (int *) safe_calloc("cmd_change", num_ctrl_cmd_param(), sizeof(int)); } if (servo_change == NULL) { servo_change = (int *) safe_calloc("servo_change", num_ctrl_cmd_param(), sizeof(int)); } // Initialize the parameter values to their defaults for (i = 0; i < num_ctrl_cmd_param(); i++) { param_val_curr[i] = ctrl_cmd_param[i].default_val; } redis = redisConnect(REDIS_HOST, REDIS_HOST_PORT); if (redis->err) { fprintf(stderr, "Connection error: %s\n", redis->errstr); exit(EXIT_FAILURE); } if (push_default) { printf("Writing default command values to the server.\n"); } else { printf("Getting current command values.\n"); } for (i = 0; i < num_ctrl_cmd_param(); i++) { if (push_default) { reply = redisCommand(redis, "SET %s %10.15g", ctrl_cmd_param[i].name, ctrl_cmd_param[i].default_val); printf("REDIS: set %s %10.15g returns %s\n", ctrl_cmd_param[i].name, ctrl_cmd_param[i].default_val, reply->str); freeReplyObject(reply); } else { reply = redisCommand(redis, "GET %s", ctrl_cmd_param[i].name); if (reply->type == REDIS_REPLY_ERROR) { printf("Error: %s\n", reply->str); } else if (reply->type != REDIS_REPLY_STRING) { printf("Unexpected type/no value: %d\n", reply->type); } else { sscanf(reply->str, "%lf", ¶m_val_curr[i]); printf("Result for %s: %10.15g\n", ctrl_cmd_param[i].name, param_val_curr[i]); } freeReplyObject(reply); } } printf("Finished retrieving current command values.\n"); return; }