Пример #1
0
/*
 * cetcd_cluster_request tries to request the whole cluster. It round-robin to next server if the request failed
 * */
void *cetcd_cluster_request(cetcd_client *cli, cetcd_request *req) {
    size_t i, count;
    cetcd_string url;
    cetcd_error *err = NULL;
    cetcd_response *resp = NULL;
    cetcd_array *addrs = NULL;
    void *res = 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;
        res = cetcd_send_request(cli->curl, req);
        sdsfree(url);

        /*api_type == syncCluster,  got address, return*/
        if (req->api_type == ETCD_MEMBERS ){
            if ((addrs = res)) {
                if ( cetcd_array_size(addrs)) {
                    return addrs;
                } else {
                    cetcd_array_destroy(addrs);
                }
            }
        } else {
            if((resp=res) && resp->err && resp->err->ecode == error_send_request_failed) {
                if (i != count-1) { 
                    cetcd_response_release(resp);
                    resp = NULL;
                }
            } else {
                /*got response, return*/
                return resp;
            }
        }
        /*try next*/
        if (i != count-1) {
            cli->picked = (cli->picked + 1) % count;
        }
    }
    /*the whole cluster failed*/
    if (req->api_type == ETCD_MEMBERS) return NULL;
    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;
}
Пример #2
0
void cetcd_watcher_release(cetcd_watcher *watcher) {
    if (watcher) {
        if (watcher->key) {
            sdsfree(watcher->key);
        }
        if (watcher->curl) {
            curl_easy_cleanup(watcher->curl);
        }
        if (watcher->parser) {
            sdsfree(watcher->parser->buf);
            cetcd_response_release(watcher->parser->resp);
            free(watcher->parser);
        }
        free(watcher);
    }
}
Пример #3
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;
}
Пример #4
0
int main(int argc, char *argv[]) {
    cetcd_client cli;
    cetcd_response *resp;
    cetcd_array addrs;

    cetcd_array_init(&addrs, 3);
    cetcd_array_append(&addrs, "http://127.0.0.1:2379");

    cetcd_client_init(&cli, &addrs);

    resp = cetcd_get(&cli, "/radar/service");
    if(resp->err) {
        printf("error :%d, %s (%s)\n", resp->err->ecode, resp->err->message, resp->err->cause);
    }
    cetcd_response_print(resp);
    cetcd_response_release(resp);

    cetcd_array_destroy(&addrs);
    cetcd_client_destroy(&cli);
    return 0;
}
Пример #5
0
static int cetcd_reap_watchers(cetcd_client *cli, CURLM *mcurl) {
    int     added, ignore;
    CURLMsg *msg;
    CURL    *curl;
    cetcd_string url;
    cetcd_watcher *watcher;
    cetcd_response *resp;
    added = 0;
    while ((msg = curl_multi_info_read(mcurl, &ignore)) != NULL) {
        if (msg->msg == CURLMSG_DONE) {
            curl = msg->easy_handle;
            curl_easy_getinfo(curl, CURLINFO_PRIVATE, &watcher);

            resp = watcher->parser->resp;
            if (msg->data.result != CURLE_OK) {
                /*try next in round-robin ways*/
                /*FIXME There is a race condition if multiple watchers failed*/
                if (watcher->attempts) {
                    cli->picked = (cli->picked+1)%(cetcd_array_size(cli->addresses));
                    url = cetcd_watcher_build_url(cli, watcher);
                    curl_easy_setopt(watcher->curl, CURLOPT_URL, url);
                    sdsfree(url);
                    curl_multi_remove_handle(mcurl, curl);
                    curl_multi_add_handle(mcurl, curl);
                    /*++added;
                     *watcher->attempts --;
                     */
                    continue;
                } else {
                    resp->err = calloc(1, sizeof(cetcd_error));
                    resp->err->ecode = error_cluster_failed;
                    resp->err->message = sdsnew("cetcd_reap_watchers: all cluster servers failed.");
                }
            }
            if (watcher->callback) {
                watcher->callback(watcher->userdata, resp);
                if (resp->err) {
                    curl_multi_remove_handle(mcurl, curl);
                    cetcd_watcher_release(watcher);
                    break;
                }
                cetcd_response_release(resp);
                watcher->parser->resp = NULL; /*surpress it be freed again by cetcd_watcher_release*/
            }
            if (!watcher->once) {
                sdsclear(watcher->parser->buf);
                watcher->parser->st = 0;
                watcher->parser->resp = calloc(1, sizeof(cetcd_response));
                if (watcher->index) {
                    watcher->index ++;
                    url = cetcd_watcher_build_url(cli, watcher);
                    curl_easy_setopt(watcher->curl, CURLOPT_URL, url);
                    sdsfree(url);
                }
                curl_multi_remove_handle(mcurl, curl);
                curl_multi_add_handle(mcurl, curl);
                ++added;
                continue;
            }
            curl_multi_remove_handle(mcurl, curl);
            cetcd_watcher_release(watcher);
        }
    }
    return added;
}