Пример #1
0
void execCommand(redisClient *c) {
    int j;
    robj **orig_argv;
    int orig_argc;

    if (!(c->flags & REDIS_MULTI)) {
        addReplySds(c,sdsnew("-ERR EXEC without MULTI\r\n"));
        return;
    }

    /* Check if we need to abort the EXEC if some WATCHed key was touched.
     * A failed EXEC will return a multi bulk nil object. */
    if (c->flags & REDIS_DIRTY_CAS) {
        freeClientMultiState(c);
        initClientMultiState(c);
        c->flags &= ~(REDIS_MULTI|REDIS_DIRTY_CAS);
        unwatchAllKeys(c);
        addReply(c,shared.nullmultibulk);
        return;
    }

    /* Replicate a MULTI request now that we are sure the block is executed.
     * This way we'll deliver the MULTI/..../EXEC block as a whole and
     * both the AOF and the replication link will have the same consistency
     * and atomicity guarantees. */
    execCommandReplicateMulti(c);

    /* Exec all the queued commands */
    unwatchAllKeys(c); /* Unwatch ASAP otherwise we'll waste CPU cycles */
    orig_argv = c->argv;
    orig_argc = c->argc;
    addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",c->mstate.count));
    for (j = 0; j < c->mstate.count; j++) {
        c->argc = c->mstate.commands[j].argc;
        c->argv = c->mstate.commands[j].argv;
        call(c,c->mstate.commands[j].cmd);
    }
    c->argv = orig_argv;
    c->argc = orig_argc;
    freeClientMultiState(c);
    initClientMultiState(c);
    c->flags &= ~(REDIS_MULTI|REDIS_DIRTY_CAS);
    /* Make sure the EXEC command is always replicated / AOF, since we
     * always send the MULTI command (we can't know beforehand if the
     * next operations will contain at least a modification to the DB). */
    server.dirty++;
}
Пример #2
0
/*
 * cetcd_cluster_request tries to request the whole cluster. It round-robin to next server if the request failed
 * */
cetcd_response *cetcd_cluster_request(cetcd_client *cli, cetcd_request *req) {
    int i;
    size_t count;
    cetcd_string url;
    cetcd_error *err;
    cetcd_response *resp;

    err = NULL;
    resp = NULL;
    count = cetcd_array_size(cli->addresses);
    
    for(i = 0; i < count; ++i) {
        url = sdscatprintf(sdsempty(), "http://%s/%s", (cetcd_string)cetcd_array_get(cli->addresses, cli->picked), req->uri);
        req->url = url;
        req->cli = cli;
        resp = cetcd_send_request(cli->curl, req);
        sdsfree(url);

        if(resp && resp->err && resp->err->ecode == error_send_request_failed) {
            if (i == count-1) {
                break;
            }
            /*try next*/
            cli->picked = (cli->picked + 1) % count;
            cetcd_response_release(resp);
            resp = NULL;
        } else {
            /*got response, return*/
            return resp;
        }
    }
    /*the whole cluster failed*/
    if (resp) {
        if(resp->err) {
            err = resp->err; /*remember last error*/
        }
        resp->err = calloc(1, sizeof(cetcd_error));
        resp->err->ecode = error_cluster_failed;
        resp->err->message = sdsnew("etcd_do_request: all cluster servers failed.");
        if (err) {
           resp->err->message = sdscatprintf(resp->err->message, " last error: %s", err->message);
           cetcd_error_release(err);
        }
        resp->err->cause = sdsdup(req->uri);
    }
    return resp;
}
Пример #3
0
void make_trace(char* path) {
	init_jcr(path);

	sds trace_file = sdsnew(path);

	char *p = trace_file + sdslen(trace_file) - 1;
	while (*p == '/')
		--p;
	*(p + 1) = 0;
	sdsupdatelen(trace_file);

	trace_file = sdscat(trace_file, ".trace");
	NOTICE("output to %s", trace_file);

	start_read_phase();
	start_chunk_phase();
	start_hash_phase();

	unsigned char code[41];

	FILE *fp = fopen(trace_file, "w");
	while (1) {
		struct chunk *c = sync_queue_pop(hash_queue);

		if (c == NULL) {
			break;
		}

		if (CHECK_CHUNK(c, CHUNK_FILE_START)) {
			destor_log(DESTOR_NOTICE, c->data);
			fprintf(fp, "file start %zd\n", strlen(c->data));
			fprintf(fp, "%s\n", c->data);

		} else if (CHECK_CHUNK(c, CHUNK_FILE_END)) {
			fprintf(fp, "file end\n");
		} else {
			hash2code(c->fp, code);
			code[40] = 0;
			fprintf(fp, "%s %d\n", code, c->size);
		}
		free_chunk(c);
	}

	fprintf(fp, "stream end");
	fclose(fp);

}
Пример #4
0
/* Mass-unblock clients because something changed in the instance that makes
 * blocking no longer safe. For example clients blocked in list operations
 * in an instance which turns from master to slave is unsafe, so this function
 * is called when a master turns into a slave.
 *
 * The semantics is to send an -UNBLOCKED error to the client, disconnecting
 * it at the same time. */
void disconnectAllBlockedClients(void) {
    listNode *ln;
    listIter li;

    listRewind(server.clients,&li);
    while((ln = listNext(&li))) {
        client *c = listNodeValue(ln);

        if (c->flags & CLIENT_BLOCKED) {
            addReplySds(c,sdsnew(
                "-UNBLOCKED force unblock from blocking operation, "
                "instance state changed (master -> slave?)\r\n"));
            unblockClient(c);
            c->flags |= CLIENT_CLOSE_AFTER_REPLY;
        }
    }
}
Пример #5
0
/* This function does exactly the revese of the function above: it gets
 * as input an integer with the xored flags and returns a string representing
 * the selected classes. The string returned is an sds string that needs to
 * be released with sdsfree(). */
sds keyspaceEventsFlagsToString(int flags) {
    sds res;

    if ((flags & REDIS_NOTIFY_ALL) == REDIS_NOTIFY_ALL)
        return sdsnew("A");
    res = sdsempty();
    if (flags & REDIS_NOTIFY_GENERIC) res = sdscatlen(res,"g",1);
    if (flags & REDIS_NOTIFY_STRING) res = sdscatlen(res,"$",1);
    if (flags & REDIS_NOTIFY_LIST) res = sdscatlen(res,"l",1);
    if (flags & REDIS_NOTIFY_SET) res = sdscatlen(res,"s",1);
    if (flags & REDIS_NOTIFY_HASH) res = sdscatlen(res,"h",1);
    if (flags & REDIS_NOTIFY_ZSET) res = sdscatlen(res,"z",1);
    if (flags & REDIS_NOTIFY_EXPIRED) res = sdscatlen(res,"x",1);
    if (flags & REDIS_NOTIFY_EVICTED) res = sdscatlen(res,"e",1);
    if (flags & REDIS_NOTIFY_KEYSPACE) res = sdscatlen(res,"K",1);
    if (flags & REDIS_NOTIFY_KEYEVENT) res = sdscatlen(res,"E",1);
    return res;
}
Пример #6
0
static bool checkPurge() {
    listNode *ln; listIter li;
    uint32    num_ok = 0;
    sds       ds     = sdsnew("DIRTY\r\n");
    listRewind(server.slaves, &li);
    while((ln = listNext(&li))) {
        cli *slave = ln->value;
        redisReply *reply;
        int fd = remoteMessage(slave->bindaddr, slave->bindport, ds, 1, &reply);
        if (fd == -1) close(fd);
        if (reply) {
            assert(reply->type == REDIS_REPLY_INTEGER);
            if (reply->integer == server.alc.stat_num_dirty_commands) num_ok++;
        }
    }
    sdsfree(ds);
    return (server.slaves->len == num_ok);
}
Пример #7
0
S triefort_destroy(const char * const path) {
  S s = triefort_ok;

  sds spath = sdsnew(path);
  spath = sdscat(spath, "/" CONFIG_FILE_NAME);

  if (!file_exists(spath)) {
    s = triefort_err_not_a_triefort;
  } else {
    if (0 != recursive_remove(path)) {
      s = triefort_err_path_could_not_be_destroyed;
    }
  }

  sdsfree(spath);

  return s;
}
Пример #8
0
cetcd_response *cetcd_send_request(CURL *curl, cetcd_request *req) {
    CURLcode res;
    cetcd_response_parser parser;
    cetcd_response *resp;

    resp = calloc(1, sizeof(cetcd_response));
    parser.resp = resp;
    parser.st = 0; /*0 should be the start state of the state machine*/
    parser.buf = sdsempty();

    curl_easy_setopt(curl, CURLOPT_URL, req->url);
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_method[req->method]);
    if (req->method == ETCD_HTTP_PUT || req->method == ETCD_HTTP_POST) {
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req->data);
    } else {
        /* We must clear post fields here:
         * We reuse the curl handle for all HTTP methods.
         * CURLOPT_POSTFIELDS would be set when issue a PUT request.
         * The field  pointed to the freed req->data. It would be 
         * reused by next request.
         * */
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
    }
    curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &parser);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cetcd_parse_response);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, req->cli->settings.verbose); 
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, req->cli->settings.connect_timeout);

    res = curl_easy_perform(curl);

    sdsfree(parser.buf);
    if (res != CURLE_OK) {
        if (resp->err == NULL) {
            resp->err = calloc(1, sizeof(cetcd_error));
            resp->err->ecode = error_send_request_failed;
            resp->err->message = sdsnew(curl_easy_strerror(res));
            resp->err->cause = sdsdup(req->url);
        }
        return resp;
    }
    return resp;
}
Пример #9
0
vuiClient * createClient(int fd)
{
    if (server.client != NULL)
    {
        close(fd);
        return NULL;
    }
    LogInfo("creat client fd:%d", fd);
    vuiClient *c = zmalloc(sizeof(vuiClient));
    memset(c, 0, sizeof(vuiClient));

    c->querybuf = sdsempty();
    c->querymsg = sdsempty();

    c->prot.method = NULL;
    c->prot.version = NULL;
    c->prot.body = NULL;
    c->prot.lenght = 0;
    c->prot.waiting = 0;

    c->res.version = "VPC/1.0";
    c->res.code = 200;
    c->res.reason = sdsnew("OK");
    c->res.body = sdsempty();
    c->res.buf = sdsempty();

    c->jsons = listCreate();

    c->fd = fd;


    anetNonBlock(NULL,fd);
    anetEnableTcpNoDelay(NULL,fd);
    if (aeCreateFileEvent(server.el, fd, AE_READABLE,
                readQueryFromClient, c) == AE_ERR)
    {
        close(fd);
        zfree(c);
        return NULL;
    }
    server.client = c;
    return c;

}
Пример #10
0
/*
 * parse master info comman and get oplog.last
 */
static void
test_repl_parse_master_info()
{
    sds buf = sdsnew("#repl\r\n"            \
                     "oplog.first:3\r\n"    \
                     "oplog.last:5\r\n"  );

    sds value = repl_parse_master_info(buf, "oplog.last");
    TEST_ASSERT("parse master info",
              strcmp(value, "5") == 0);
    sdsfree(value);

    value = repl_parse_master_info(buf, "oplog.last2");
    TEST_ASSERT("parse master info",
              value == NULL);
    sdsfree(value);

    sdsfree(buf);
}
Пример #11
0
/* This should be called from any function PUSHing into lists.
 * 'c' is the "pushing client", 'key' is the key it is pushing data against,
 * 'ele' is the element pushed.
 *
 * If the function returns 0 there was no client waiting for a list push
 * against this key.
 *
 * If the function returns 1 there was a client waiting for a list push
 * against this key, the element was passed to this client thus it's not
 * needed to actually add it to the list and the caller should return asap. */
int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele) {
    struct dictEntry *de;
    redisClient *receiver;
    list *l;
    listNode *ln;

    de = dictFind(c->db->blocking_keys,key);
    if (de == NULL) return 0;
    l = dictGetEntryVal(de);
    ln = listFirst(l);
    redisAssert(ln != NULL);
    receiver = ln->value;

    addReplySds(receiver,sdsnew("*2\r\n"));
    addReplyBulk(receiver,key);
    addReplyBulk(receiver,ele);
    unblockClientWaitingData(receiver);
    return 1;
}
Пример #12
0
/* Populates the Redis Command Table starting from the hard coded list
 * we have in the rct_command.h file. */
void populateCommandTable(dict *commands) {
    
    int ret;
    int j;
    int numcommands;

    if(commands == NULL)
    {
        return;
    }

    numcommands = sizeof(rctCommandTable)/sizeof(RCTCommand);

    for (j = 0; j < numcommands; j++) {
        RCTCommand *c = rctCommandTable+j;

        ret = dictAdd(commands, sdsnew(c->name), c);
    }
}
Пример #13
0
sds _masterGetStatus() {
    /*TODO: calculate cache increase speed,
     * then adopt a suitable stale-cache freeing strategy
     * Three involved params:
     * (1) master sleep,
     * (2) ae loop wait,
     * and (3) number of stale entries in one ae loop
     */

    sds status = sdsempty();//sdsfromlonglong(master_total_mem);
    status = sdscatprintf(status,"TOL RAM: %-6.2lfMB\tUSED RAM: %-6.2lf\n",
                          BYTES_TO_MEGABYTES(MASTER_MAX_AVAIL_MEM),
                          BYTES_TO_MEGABYTES(master_total_mem));
#if (CCACHE_LOG_LEVEL == CCACHE_DEBUG)
    status = sdscatprintf(status,"Detail:\n");
    status = sdscatprintf(status,"%-3s %-32s: %-6s\n"," ","KEY","MEM");
    dictIterator *di = dictGetIterator(master_cache);
    dictEntry *de;
    int idx = 1;
    while((de = dictNext(di)) != NULL) {
        objSds *value = (objSds*)dictGetEntryVal(de);
        if(value) {
            if(value->ptr) {
                status = sdscatprintf(status,"%-3d %-32s: %-6ld\n",
                                        idx++,
                                        (char*)dictGetEntryKey(de),
                                        sdslen(value->ptr));
            }
            else {
                status = sdscatprintf(status,"%-3d %-32s: %-6s\n",
                                        idx++,
                                        (char*)dictGetEntryKey(de),
                                        "WAITING");
            }
        }
    }
    dictReleaseIterator(di);
#endif
    sds status_reply = sdsnew("HTTP/1.1 200 OK\r\n");
    status_reply = sdscatprintf(status_reply,"Content-Length: %ld\r\n\r\n%s",sdslen(status),status);
    sdsfree(status);
    return status_reply;
}
Пример #14
0
void slaveofCommand(redisClient *c) {
    if (!strcasecmp(c->argv[1]->ptr,"no") &&
        !strcasecmp(c->argv[2]->ptr,"one")) {
        if (server.masterhost) {
            sdsfree(server.masterhost);
            server.masterhost = NULL;
            if (server.master) freeClient(server.master);
            if (server.repl_state == REDIS_REPL_TRANSFER)
                replicationAbortSyncTransfer();
            else if (server.repl_state == REDIS_REPL_CONNECTING ||
                     server.repl_state == REDIS_REPL_RECEIVE_PONG)
                undoConnectWithMaster();
            server.repl_state = REDIS_REPL_NONE;
            redisLog(REDIS_NOTICE,"MASTER MODE enabled (user request)");
        }
    } else {
        long port;

        if ((getLongFromObjectOrReply(c, c->argv[2], &port, NULL) != REDIS_OK))
            return;

        /* Check if we are already attached to the specified slave */
        if (server.masterhost && !strcasecmp(server.masterhost,c->argv[1]->ptr)
            && server.masterport == port) {
            redisLog(REDIS_NOTICE,"SLAVE OF would result into synchronization with the master we are already connected with. No operation performed.");
            addReplySds(c,sdsnew("+OK Already connected to specified master\r\n"));
            return;
        }
        /* There was no previous master or the user specified a different one,
         * we can continue. */
        sdsfree(server.masterhost);
        server.masterhost = sdsdup(c->argv[1]->ptr);
        server.masterport = port;
        if (server.master) freeClient(server.master);
        disconnectSlaves(); /* Force our slaves to resync with us as well. */
        if (server.repl_state == REDIS_REPL_TRANSFER)
            replicationAbortSyncTransfer();
        server.repl_state = REDIS_REPL_CONNECT;
        redisLog(REDIS_NOTICE,"SLAVE OF %s:%d enabled (user request)",
            server.masterhost, server.masterport);
    }
    addReply(c,shared.ok);
}
Пример #15
0
/* Use this function if the caller has already read the data. It will
 * feed bytes to the reply parser.
 *
 * After this function is called, you may use redisContextReadReply to
 * see if there is a reply available. */
int redisBufferReadDone(redisContext *c, char *buf, int nread) {
    if (nread == -1) {
        if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
            /* Try again later */
        } else {
            __redisSetError(c,REDIS_ERR_IO,NULL);
            return REDIS_ERR;
        }
    } else if (nread == 0) {
        __redisSetError(c,REDIS_ERR_EOF, sdsnew("Server closed the connection"));
        return REDIS_ERR;
    } else {
        if (redisReaderFeed(c->reader,buf,nread) != REDIS_OK) {
            __redisSetError(c,c->reader->err,c->reader->errstr);
            return REDIS_ERR;
        }
    }
    return REDIS_OK;
}
Пример #16
0
Файл: red.c Проект: nanopack/red
static int
parse_options(int argc, char **argv)
{
	int i;

	if (argc == 1)
		usage();

	for (i = 1; i < argc; i++) {
		int lastarg = i==argc-1;

		if (!strcmp(argv[i],"-h") && !lastarg) {
			sdsfree(config.redd_ip);
			config.redd_ip = sdsnew(argv[++i]);
		} else if (!strcmp(argv[i],"-h") && lastarg) {
			usage();
		} else if (!strcmp(argv[i],"--help")) {
			usage();
		} else if (!strcmp(argv[i],"-p") && !lastarg) {
			config.redd_port = atoi(argv[++i]);
		} else if (!strcmp(argv[i],"-v") || !strcmp(argv[i], "--version")) {
			printf("red %s\n", RED_VERSION);
			exit(0);
		} else if (!strcmp(argv[i],"-y") || !strcmp(argv[i], "--yaml")) {
			config.yaml_out = 1;
		} else if (!strcmp(argv[i],"-n") || !strcmp(argv[i], "--nooutput")) {
			config.no_output = 1;
		} else {
			if (argv[i][0] == '-') {
				fprintf(stderr,
					"Unrecognized option or bad number of args for: '%s'\n",
					argv[i]);
				exit(1);
			} else {
				/* Likely the command name, stop here. */
				break;
			}
		}
	}

	return i;
}
Пример #17
0
void typeCommand(redisClient *c) {
    robj *o;
    char *type;

    o = lookupKeyRead(c->db,c->argv[1]);
    if (o == NULL) {
        type = "+none";
    } else {
        switch(o->type) {
        case REDIS_STRING: type = "+string"; break;
        case REDIS_LIST: type = "+list"; break;
        case REDIS_SET: type = "+set"; break;
        case REDIS_ZSET: type = "+zset"; break;
        case REDIS_HASH: type = "+hash"; break;
        default: type = "+unknown"; break;
        }
    }
    addReplySds(c,sdsnew(type));
    addReply(c,shared.crlf);
}
Пример #18
0
/* Use this function to handle a read event on the descriptor. It will try
 * and read some bytes from the socket and feed them to the reply parser.
 *
 * After this function is called, you may use redisContextReadReply to
 * see if there is a reply available. */
int redisBufferRead(redisContext *c) {
    char buf[2048];
    int nread = read(c->fd,buf,sizeof(buf));
    if (nread == -1) {
        if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
            /* Try again later */
        } else {
            __redisSetError(c,REDIS_ERR_IO,NULL);
            return REDIS_ERR;
        }
    } else if (nread == 0) {
        __redisSetError(c,REDIS_ERR_EOF,
            sdsnew("Server closed the connection"));
        return REDIS_ERR;
    } else {
        __redisCreateReplyReader(c);
        redisReplyReaderFeed(c->reader,buf,nread);
    }
    return REDIS_OK;
}
Пример #19
0
static response *resolve_stream(const char *url)
{
    request *request = http_get(url);
    response *response = http_send(request);

    if (http_read_body(response) < 0 && response->status != 302) {
        fprintf(stderr, "request failed %s", url); 
        return NULL;
    }

    sds stream_url = sdsnew(http_header(response, "Location"));

    free_response(response);

    request = http_get(stream_url);
    response = http_send(request);
    
    sdsfree(stream_url);

    return response;
}
Пример #20
0
void replicationFeedMonitors(redisClient *c, list *monitors, int dictid, robj **argv, int argc) {
    listNode *ln;
    listIter li;
    int j, port;
    sds cmdrepr = sdsnew("+");
    robj *cmdobj;
    char ip[32];
    struct timeval tv;

    gettimeofday(&tv,NULL);
    cmdrepr = sdscatprintf(cmdrepr,"%ld.%06ld ",(long)tv.tv_sec,(long)tv.tv_usec);
    if (c->flags & REDIS_LUA_CLIENT) {
        cmdrepr = sdscatprintf(cmdrepr,"[%d lua] ",dictid);
    } else if (c->flags & REDIS_UNIX_SOCKET) {
        cmdrepr = sdscatprintf(cmdrepr,"[%d unix:%s] ",dictid,server.unixsocket);
    } else {
        anetPeerToString(c->fd,ip,&port);
        cmdrepr = sdscatprintf(cmdrepr,"[%d %s:%d] ",dictid,ip,port);
    }

    for (j = 0; j < argc; j++) {
        if (argv[j]->encoding == REDIS_ENCODING_INT) {
            cmdrepr = sdscatprintf(cmdrepr, "\"%ld\"", (long)argv[j]->ptr);
        } else {
            cmdrepr = sdscatrepr(cmdrepr,(char*)argv[j]->ptr,
                        sdslen(argv[j]->ptr));
        }
        if (j != argc-1)
            cmdrepr = sdscatlen(cmdrepr," ",1);
    }
    cmdrepr = sdscatlen(cmdrepr,"\r\n",2);
    cmdobj = createObject(REDIS_STRING,cmdrepr);

    listRewind(monitors,&li);
    while((ln = listNext(&li))) {
        redisClient *monitor = ln->value;
        addReply(monitor,cmdobj);
    }
    decrRefCount(cmdobj);
}
Пример #21
0
S triefort_open(TF ** const fort, const HCFG * const hashcfg, const char * const path) {
  NULLCHK(fort);
  NULLCHK(hashcfg);
  NULLCHK(path);

  S s;

  sds fortpath = sdsnew(path);
  sds cfgpath = sdsdup(fortpath);
  cfgpath = sdscat(cfgpath, "/" CONFIG_FILE_NAME);

  if (!file_exists(cfgpath)) {
    s = triefort_err_not_a_triefort;
  } else {
    *fort = calloc(1, sizeof(**fort));
    TF * f = *fort;

    f->path = fortpath; // *fort takes ownership of `fortpath`
    f->hcfg = hashcfg;

    if (triefort_ok == (s = load_cfg(&f->cfg, cfgpath))) {
      if (!validate_cfg(&(*fort)->cfg)) {
        s = triefort_err_invalid_config;
      }

      if (0 != strncmp(hashcfg->fn_name, (*fort)->cfg.hash_name, MAX_LEN_HASH_NAME)) {
        s = triefort_err_hash_name_mismatch;
      }

      if (triefort_ok != s) {
        triefort_close(*fort);
        *fort = NULL;
      }
    }
  }

  sdsfree(cfgpath);

  return s;
}
Пример #22
0
void cetcd_client_init(cetcd_client *cli, cetcd_array *addresses) {
    size_t i;
    cetcd_array *addrs;
    curl_global_init(CURL_GLOBAL_ALL);
    srand(time(0));

    cli->keys_space =   "v2/keys";
    cli->stat_space =   "v2/stat";
    cli->member_space = "v2/members";
    cli->curl = curl_easy_init();
    
    addrs = cetcd_array_create(cetcd_array_size(addresses));
    for (i=0; i<cetcd_array_size(addresses); ++i) {
        cetcd_array_append(addrs, sdsnew(cetcd_array_get(addresses, i)));
    }
    
    cli->addresses = cetcd_array_shuffle(addrs);
    cli->picked = rand() % (cetcd_array_size(cli->addresses));

    cli->settings.verbose = 0;
    cli->settings.connect_timeout = 1;
    cli->settings.read_timeout = 1;  /*not used now*/
    cli->settings.write_timeout = 1; /*not used now*/

    cetcd_array_init(&cli->watchers, 10);

    /* Set CURLOPT_NOSIGNAL to 1 to work around the libcurl bug:
     *  http://stackoverflow.com/questions/9191668/error-longjmp-causes-uninitialized-stack-frame
     *  http://curl.haxx.se/mail/lib-2008-09/0197.html
     * */
    curl_easy_setopt(cli->curl, CURLOPT_NOSIGNAL, 1L);

#if LIBCURL_VERSION_NUM >= 0x071900
    curl_easy_setopt(cli->curl, CURLOPT_TCP_KEEPALIVE, 1L);
    curl_easy_setopt(cli->curl, CURLOPT_TCP_KEEPINTVL, 1L); /*the same as go-etcd*/
#endif
    curl_easy_setopt(cli->curl, CURLOPT_USERAGENT, "cetcd");
    curl_easy_setopt(cli->curl, CURLOPT_POSTREDIR, 3L);     /*post after redirecting*/
}
Пример #23
0
void slaveofCommand(redisClient *c) {
    if (!strcasecmp(c->argv[1]->ptr,"no") &&
        !strcasecmp(c->argv[2]->ptr,"one")) {
        if (server.masterhost) {//已经是个slave了,需要关闭之
            sdsfree(server.masterhost);
            server.masterhost = NULL;
            if (server.master) freeClient(server.master);
            cancelReplicationHandshake();
            server.repl_state = REDIS_REPL_NONE;
            redisLog(REDIS_NOTICE,"MASTER MODE enabled (user request)");
        }
    } else {
        long port;

        if ((getLongFromObjectOrReply(c, c->argv[2], &port, NULL) != REDIS_OK))
            return;

        /* Check if we are already attached to the specified slave */
        if (server.masterhost && !strcasecmp(server.masterhost,c->argv[1]->ptr)
            && server.masterport == port) {
            redisLog(REDIS_NOTICE,"SLAVE OF would result into synchronization with the master we are already connected with. No operation performed.");
            addReplySds(c,sdsnew("+OK Already connected to specified master\r\n"));
            return;
        }
        /* There was no previous master or the user specified a different one,
         * we can continue. */
        sdsfree(server.masterhost);
        server.masterhost = sdsdup(c->argv[1]->ptr);
        server.masterport = port;
        if (server.master) freeClient(server.master);//直接关闭之前的master连接,readSyncBulkPayload接收完RDB文件会设置这个的。
        disconnectSlaves(); /* Force our slaves to resync with us as well. */
        cancelReplicationHandshake();
		//下面设置这个的状态为需要连接master, 这样在serverCron定时任务会每秒调用replicationCron,进而会调用connectWithMaster进行重连的。
        server.repl_state = REDIS_REPL_CONNECT;
        redisLog(REDIS_NOTICE,"SLAVE OF %s:%d enabled (user request)",
            server.masterhost, server.masterport);
    }
    addReply(c,shared.ok);
}
Пример #24
0
cetcd_watcher *cetcd_watcher_create(cetcd_string key, uint64_t index,
        int recursive, int once, watcher_callback callback, void *userdata) {
    cetcd_watcher *watcher;

    watcher = calloc(1, sizeof(cetcd_watcher));
    watcher->key = sdsnew(key);
    watcher->index = index;
    watcher->recursive = recursive;
    watcher->once = once;
    watcher->callback = callback;
    watcher->userdata = userdata;
    watcher->curl = curl_easy_init();

    watcher->parser = calloc(1, sizeof(cetcd_response_parser));
    watcher->parser->st = 0;
    watcher->parser->buf = sdsempty();
    watcher->parser->resp = calloc(1, sizeof(cetcd_response));

    watcher->array_index = -1;

    return watcher;
}
Пример #25
0
int main(int argc, char **argv) {
    int firstarg, j;
    char **argvcopy;
    struct redisCommand *rc;

    config.hostip = "127.0.0.1";
    config.hostport = 6379;
    config.repeat = 1;

    firstarg = parseOptions(argc,argv);
    argc -= firstarg;
    argv += firstarg;
    
    /* Turn the plain C strings into Sds strings */
    argvcopy = zmalloc(sizeof(char*)*argc+1);
    for(j = 0; j < argc; j++)
        argvcopy[j] = sdsnew(argv[j]);

    if (argc < 1) {
        fprintf(stderr, "usage: redis-cli [-h host] [-p port] [-r repeat_times] cmd arg1 arg2 arg3 ... argN\n");
        fprintf(stderr, "usage: echo \"argN\" | redis-cli [-h host] [-p port] -r [repeat_times] cmd arg1 arg2 ... arg(N-1)\n");
        fprintf(stderr, "\nIf a pipe from standard input is detected this data is used as last argument.\n\n");
        fprintf(stderr, "example: cat /etc/passwd | redis-cli set my_passwd\n");
        fprintf(stderr, "example: redis-cli get my_passwd\n");
        fprintf(stderr, "example: redis-cli -r 100 lpush mylist x\n");
        exit(1);
    }

    /* Read the last argument from stdandard input if needed */
    if ((rc = lookupCommand(argv[0])) != NULL) {
        if (rc->arity > 0 && argc == rc->arity-1) {
            sds lastarg = readArgFromStdin();
            argvcopy[argc] = lastarg;
            argc++;
        }
    }

    return cliSendCommand(argc, argvcopy);
}
Пример #26
0
static int
slotsmgrt_get_socket(redisClient *c, sds host, sds port, int timeout) {
    sds name = sdsempty();
    name = sdscatlen(name, host, sdslen(host));
    name = sdscatlen(name, ":", 1);
    name = sdscatlen(name, port, sdslen(port));

    slotsmgrt_sockfd *pfd = dictFetchValue(server.slotsmgrt_cached_sockfds, name);
    if (pfd != NULL) {
        sdsfree(name);
        pfd->lasttime = server.unixtime;
        return pfd->fd;
    }
    
    int fd = anetTcpNonBlockConnect(server.neterr, host, atoi(port));
    if (fd == -1) {
        redisLog(REDIS_WARNING, "slotsmgrt: connect to target %s:%s, error = '%s'",
                host, port, server.neterr);
        sdsfree(name);
        addReplyErrorFormat(c,"Can't connect to target node: %s", server.neterr);
        return -1;
    }
    anetEnableTcpNoDelay(server.neterr, fd);
    if ((aeWait(fd, AE_WRITABLE, timeout) & AE_WRITABLE) == 0) {
        redisLog(REDIS_WARNING, "slotsmgrt: connect to target %s:%s, aewait error = '%s'",
                host, port, server.neterr);
        sdsfree(name);
        close(fd);
        addReplySds(c, sdsnew("-IOERR error or timeout connecting to the client\r\n"));
        return -1;
    }
    redisLog(REDIS_WARNING, "slotsmgrt: connect to target %s:%s", host, port);

    pfd = zmalloc(sizeof(*pfd));
    pfd->fd = fd;
    pfd->lasttime = server.unixtime;
    dictAdd(server.slotsmgrt_cached_sockfds, name, pfd);
    return fd;
}
Пример #27
0
static int process_command(sub_client *c)
{
    srv_log(LOG_DEBUG, "c->argv[0]: %s", c->argv[0]);
    sds name = sdsnew(c->argv[0]);
    sdstolower(name);

    sub_command *cmd = ght_get(server.sub_commands, sdslen(name), name);
    if (!cmd) {
        add_reply_error_fmt(c, "unknown command '%s'", name);
    } else if ((cmd->arity > 0 && cmd->arity != c->argc) ||
               (c->argc < -cmd->arity)) {
        add_reply_error_fmt(c, "wrong number of arguments for '%s' command",
                name);
    } else {
        srv_log(LOG_DEBUG, "cmd name: %s arity: %d", cmd->name, cmd->arity);
        cmd->proc(c);
    }

    sdsfree(name);

    return SUBCLI_OK;
}
Пример #28
0
void parg_asset_preload(parg_token id)
{
    if (!_pngsuffix) {
        _pngsuffix = sdsnew(".png");
    }
    sds filename = parg_token_to_sds(id);
    parg_buffer* buf = parg_buffer_from_path(filename);
    parg_assert(buf, "Unable to load asset");
    if (sdslen(filename) > 4) {
        sds suffix = sdsdup(filename);
        sdsrange(suffix, -4, -1);
        if (!sdscmp(suffix, _pngsuffix)) {
            unsigned char* decoded;
            unsigned dims[3] = {0, 0, 4};
            unsigned char* filedata = parg_buffer_lock(buf, PARG_READ);
            unsigned err = lodepng_decode_memory(&decoded, &dims[0], &dims[1],
                    filedata, parg_buffer_length(buf), LCT_RGBA, 8);
            parg_assert(err == 0, "PNG decoding error");
            parg_buffer_free(buf);
            int nbytes = dims[0] * dims[1] * dims[2];
            buf = parg_buffer_alloc(nbytes + 12, PARG_CPU);
            int* ptr = parg_buffer_lock(buf, PARG_WRITE);
            *ptr++ = dims[0];
            *ptr++ = dims[1];
            *ptr++ = dims[2];
            memcpy(ptr, decoded, nbytes);
            free(decoded);
            parg_buffer_unlock(buf);
        }
        sdsfree(suffix);
    }
    if (!_asset_registry) {
        _asset_registry = kh_init(assmap);
    }
    int ret;
    int iter = kh_put(assmap, _asset_registry, id, &ret);
    kh_value(_asset_registry, iter) = buf;
}
Пример #29
0
void server_accept_client(struct evconnlistener *listener, evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr)
{
    int port = ntohs(((struct sockaddr_in*)addr)->sin_port);
    sds ip = sdsnew(inet_ntoa(((struct sockaddr_in*)addr)->sin_addr));

    server.client_connected++;

    log_info("Accepted client socket from %s:%d, current[%d], max[%d], total[%"PRIu64"]", ip, port, server.client_current + 1, server.client_max, server.client_connected);
    if(server.client_current >= server.client_max)
    {
        ssize_t wl;
        log_warn("Reached max connection: %d, client will be closed.", server.client_current + 1);
        sds msg = sdscatprintf(sdsempty(), "%s 1%sMax connection error.", ZR_CMD_REP_ERR, ZR_MSG_NL);
        wl = write(sock, msg, sdslen(msg));
        sdsfree(msg);
        close(sock);
        return;
    }


    //struct client *c = client_alloc(sock, (struct sockaddr_in*)addr);
    client_alloc(sock, (struct sockaddr_in*)addr);
}
Пример #30
0
int main(int argc, const char **argv) {
    int i;
    char *data, *cmd;
    int len;

    client c;

    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);

    config.numclients = 50;
    config.requests = 10000;
    config.liveclients = 0;
    config.el = aeCreateEventLoop(1024*10);
    aeCreateTimeEvent(config.el,1,showThroughput,NULL,NULL);
    config.keepalive = 1;
    config.datasize = 3;
    config.pipeline = 1;
    config.randomkeys = 0;
    config.randomkeys_keyspacelen = 0;
    config.quiet = 0;
    config.csv = 0;
    config.loop = 0;
    config.idlemode = 0;
    config.latency = NULL;
    config.clients = listCreate();
    config.hostip = "127.0.0.1";
    config.hostport = 6379;
    config.hostsocket = NULL;
    config.tests = NULL;
    config.dbnum = 0;

    i = parseOptions(argc,argv);
    argc -= i;
    argv += i;

//    printf ("SET PAGE POOL SIZE\n");
//    set_page_pool_size(config.requests);
    config.latency = zmalloc(sizeof(long long)*config.requests);

    if (config.keepalive == 0) {
        printf("WARNING: keepalive disabled, you probably need 'echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse' for Linux and 'sudo sysctl -w net.inet.tcp.msl=1000' for Mac OS X in order to use a lot of clients/requests\n");
    }

    if (config.idlemode) {
        printf("Creating %d idle connections and waiting forever (Ctrl+C when done)\n", config.numclients);
        c = createClient("",0,NULL); /* will never receive a reply */
        createMissingClients(c);
        aeMain(config.el);
        /* and will wait for every */
    }

    /* Run benchmark with command in the remainder of the arguments. */
    if (argc) {
        sds title = sdsnew(argv[0]);
        for (i = 1; i < argc; i++) {
            title = sdscatlen(title, " ", 1);
            title = sdscatlen(title, (char*)argv[i], strlen(argv[i]));
        }

        do {
            len = redisFormatCommandArgv(&cmd,argc,argv,NULL);
            benchmark(title,cmd,len);
            free(cmd);
        } while(config.loop);

        return 0;
    }

    /* Run default benchmark suite. */
    do {
        data = zmalloc(config.datasize+1);
        memset(data,'x',config.datasize);
        data[config.datasize] = '\0';

        if (test_is_selected("ping_inline") || test_is_selected("ping"))
            benchmark("PING_INLINE","PING\r\n",6);

        if (test_is_selected("ping_mbulk") || test_is_selected("ping")) {
            len = redisFormatCommand(&cmd,"PING");
            benchmark("PING_BULK",cmd,len);
            free(cmd);
        }

        if (test_is_selected("set")) {
            len = redisFormatCommand(&cmd,"SET key:__rand_int__ %s",data);
            benchmark("SET",cmd,len);
            free(cmd);
        }

        if (test_is_selected("get")) {
            len = redisFormatCommand(&cmd,"GET key:__rand_int__");
            benchmark("GET",cmd,len);
            free(cmd);
        }

        if (test_is_selected("incr")) {
            len = redisFormatCommand(&cmd,"INCR counter:__rand_int__");
            benchmark("INCR",cmd,len);
            free(cmd);
        }

        if (test_is_selected("lpush")) {
            len = redisFormatCommand(&cmd,"LPUSH mylist %s",data);
            benchmark("LPUSH",cmd,len);
            free(cmd);
        }

        if (test_is_selected("lpop")) {
            len = redisFormatCommand(&cmd,"LPOP mylist");
            benchmark("LPOP",cmd,len);
            free(cmd);
        }

        if (test_is_selected("sadd")) {
            len = redisFormatCommand(&cmd,
                "SADD myset element:__rand_int__");
            benchmark("SADD",cmd,len);
            free(cmd);
        }

        if (test_is_selected("spop")) {
            len = redisFormatCommand(&cmd,"SPOP myset");
            benchmark("SPOP",cmd,len);
            free(cmd);
        }

        if (test_is_selected("lrange") ||
            test_is_selected("lrange_100") ||
            test_is_selected("lrange_300") ||
            test_is_selected("lrange_500") ||
            test_is_selected("lrange_600"))
        {
            len = redisFormatCommand(&cmd,"LPUSH mylist %s",data);
            benchmark("LPUSH (needed to benchmark LRANGE)",cmd,len);
            free(cmd);
        }

        if (test_is_selected("lrange") || test_is_selected("lrange_100")) {
            len = redisFormatCommand(&cmd,"LRANGE mylist 0 99");
            benchmark("LRANGE_100 (first 100 elements)",cmd,len);
            free(cmd);
        }

        if (test_is_selected("lrange") || test_is_selected("lrange_300")) {
            len = redisFormatCommand(&cmd,"LRANGE mylist 0 299");
            benchmark("LRANGE_300 (first 300 elements)",cmd,len);
            free(cmd);
        }

        if (test_is_selected("lrange") || test_is_selected("lrange_500")) {
            len = redisFormatCommand(&cmd,"LRANGE mylist 0 449");
            benchmark("LRANGE_500 (first 450 elements)",cmd,len);
            free(cmd);
        }

        if (test_is_selected("lrange") || test_is_selected("lrange_600")) {
            len = redisFormatCommand(&cmd,"LRANGE mylist 0 599");
            benchmark("LRANGE_600 (first 600 elements)",cmd,len);
            free(cmd);
        }

        if (test_is_selected("mset")) {
            const char *argv[21];
            argv[0] = "MSET";
            for (i = 1; i < 21; i += 2) {
                argv[i] = "key:__rand_int__";
                argv[i+1] = data;
            }
            len = redisFormatCommandArgv(&cmd,21,argv,NULL);
            benchmark("MSET (10 keys)",cmd,len);
            free(cmd);
        }

        if (!config.csv) printf("\n");
    } while(config.loop);

    return 0;
}