size_t
shardcache_client_offset(shardcache_client_t *c, void *key, size_t klen, uint32_t offset, void *data, uint32_t dlen)
{
    int fd = -1;
    char *addr = select_node(c, key, klen, &fd);
    if (fd < 0) {
        c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK;
        snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr);
        return 0;
    }

    fbuf_t value = FBUF_STATIC_INITIALIZER;
    int rc = offset_from_peer(addr, (char *)c->auth, SHC_HDR_SIGNATURE_SIP, key, klen, offset, dlen, &value, fd);
    if (rc == 0) {
        uint32_t to_copy = dlen > fbuf_used(&value) ? fbuf_used(&value) : dlen;
        if (data)
            memcpy(data, fbuf_data(&value), to_copy);

        c->errno = SHARDCACHE_CLIENT_OK;
        c->errstr[0] = 0;

        connections_pool_add(c->connections, addr, fd);
        fbuf_destroy(&value);
        return to_copy;
    } else {
        close(fd);
        c->errno = SHARDCACHE_CLIENT_ERROR_NODE;
        snprintf(c->errstr, sizeof(c->errstr), "Can't fetch data from node '%s'", addr);
    }
    fbuf_destroy(&value);
    return 0;
}
size_t
shardcache_client_get(shardcache_client_t *c, void *key, size_t klen, void **data)
{
    int fd = -1;
    char *addr = select_node(c, key, klen, &fd);

    if (fd < 0) {
        c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK;
        snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr);
        return 0;
    }

    fbuf_t value = FBUF_STATIC_INITIALIZER;
    int rc = fetch_from_peer(addr, (char *)c->auth, SHC_HDR_SIGNATURE_SIP, key, klen, &value, fd);
    if (rc == 0) {
        size_t size = fbuf_used(&value);
        if (data)
            *data = fbuf_data(&value);
        else
            fbuf_destroy(&value);

        c->errno = SHARDCACHE_CLIENT_OK;
        c->errstr[0] = 0;

        connections_pool_add(c->connections, addr, fd);
        return size;
    } else {
        close(fd);
        c->errno = SHARDCACHE_CLIENT_ERROR_NODE;
        snprintf(c->errstr, sizeof(c->errstr), "Can't fetch data from node '%s'", addr);
        return 0;
    }
    return 0;
}
int
shardcache_client_migration_begin(shardcache_client_t *c, shardcache_node_t **nodes, int num_nodes)
{
    fbuf_t mgb_message = FBUF_STATIC_INITIALIZER;

    int i;
    for (i = 0; i < num_nodes; i++) {
        if (i > 0)
            fbuf_add(&mgb_message, ",");
        fbuf_printf(&mgb_message, "%s:%s", shardcache_node_get_string(nodes[i]));
    }

    for (i = 0; i < c->num_shards; i++) {
        char *addr = shardcache_node_get_address(c->shards[i]);
        int fd = connections_pool_get(c->connections, addr);
        if (fd < 0) {
            c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK;
            snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr);
            fbuf_destroy(&mgb_message);
            return -1;
        }

        int rc = migrate_peer(addr,
                              (char *)c->auth,
                              SHC_HDR_SIGNATURE_SIP,
                              fbuf_data(&mgb_message),
                              fbuf_used(&mgb_message), fd);
        if (rc != 0) {
            close(fd);
            c->errno = SHARDCACHE_CLIENT_ERROR_NODE;
            snprintf(c->errstr, sizeof(c->errstr), "Node '%s' (%s) didn't aknowledge the migration\n",
                    shardcache_node_get_label(c->shards[i]), addr);
            fbuf_destroy(&mgb_message);
            // XXX - should we abort migration on peers that have been notified (if any)?
            return -1;
        }
        connections_pool_add(c->connections, addr, fd);
    }
    fbuf_destroy(&mgb_message);

    c->errno = SHARDCACHE_CLIENT_OK;
    c->errstr[0] = 0;

    return 0;
}
Beispiel #4
0
void
fbuf_move(fbuf_t *fbufsrc, fbuf_t *fbufdst)
{
    DEBUG_FBUF_INFO(fbufsrc, "source");
    DEBUG_FBUF_INFO(fbufsrc, "destination");
    fbuf_destroy(fbufdst);
    bcopy(fbufsrc, fbufdst, sizeof(fbuf_t));
    fbufsrc->data = NULL;
    fbufsrc->used = fbufsrc->len = fbufsrc->skip = 0;
    fbufsrc->id = __sync_fetch_and_add(&fbuf_count, 1);
}