コード例 #1
0
static ngx_int_t __on_write_master1_complete(
    uint8_t method,
    ngx_bool_t has_tb,
    ngx_http_request_t *r,
    ngx_http_hustdb_ha_write_ctx_t * ctx)
{
    __update_error(method, r->headers_out.status, ctx);
    ctx->base.peer = ctx->base.peer->next;
    ngx_bool_t alive = ngx_http_peer_is_alive(ctx->base.peer->peer);
    ngx_http_hustdb_ha_main_conf_t * mcf = hustdb_ha_get_module_main_conf(r);
    if (mcf->debug_sync)
    {
        alive = false;
    }
    if (alive) // master2
    {
        ctx->state = STATE_WRITE_MASTER2;
        return ngx_http_run_subrequest(r, &ctx->base.base, ctx->base.peer->peer);
    }

    // master2 dead
    ++ctx->error_count;
    ctx->error_peer = ctx->base.peer;

    if (ctx->error_count > 1) // both master1 & master2 fail
    {
        return hustdb_ha_send_response(NGX_HTTP_NOT_FOUND, NULL, NULL, r);
    }

    return __write_sync_data(method, has_tb, r, ctx);
}
コード例 #2
0
static ngx_int_t __write_sync_data(
    uint8_t method,
    ngx_bool_t has_tb,
    ngx_http_request_t *r,
    ngx_http_hustdb_ha_write_ctx_t * ctx)
{
    do
    {
        time_t now = time(NULL);
        uint32_t ttl = (0 == ctx->ttl) ? 0 : (uint32_t) (now + ctx->ttl);

        ngx_buf_t * value = NULL;
        ngx_buf_t * head = __encode_head(method, ctx->proto, has_tb, ctx->base.version, ctx->base.key, ctx->base.tb, ttl, r->pool);
        if (r->request_body)
        {
            if (!ngx_http_insert_head_to_body(head, r))
            {
                break;
            }
            value = ngx_http_get_request_body(r);
        }
        else
        {
            value = head;
        }

        if (!value)
        {
            break;
        }

        ngx_http_hustdb_ha_main_conf_t * mcf = hustdb_ha_get_module_main_conf(r);
        ngx_str_t * server = &ctx->error_peer->peer->server;
        if (!hustdb_ha_write_log(&mcf->zlog_mdc, server, value, r->pool))
        {
            break;
        }

        static ngx_str_t SYNC_KEY = ngx_string("Sync");
        if (!ngx_http_add_field_to_headers_out(&SYNC_KEY, server, r))
        {
            break;
        }

        return hustdb_ha_send_response(NGX_HTTP_OK, ctx->base.version, NULL, r);
    } while (0);

    return hustdb_ha_send_response(NGX_HTTP_NOT_FOUND, NULL, NULL, r);
}
コード例 #3
0
ngx_int_t hustdb_ha_sync_status_handler(ngx_str_t * backend_uri, ngx_http_request_t *r)
{
    ngx_http_hustdb_ha_main_conf_t * mcf = hustdb_ha_get_module_main_conf(r);
    if (!mcf)
    {
        return NGX_ERROR;
    }
    ngx_int_t rc = hustdb_ha_fetch_sync_data(&mcf->sync_status_uri, &mcf->sync_status_args,
        &mcf->sync_user, &mcf->sync_passwd, mcf->sync_peer, r);
    if (NGX_ERROR == rc)
    {
        return ngx_http_send_response_imp(NGX_HTTP_NOT_FOUND, NULL, r);
    }
    return NGX_DONE;
}
コード例 #4
0
static ngx_bool_t __set_write_context(const char * key, ngx_bool_t has_tb, ngx_http_request_t *r, write_ctx_t * ctx)
{
    if (key)
    {
        ctx->key = key;
    }
    else
    {
        ctx->key = ngx_http_get_param_val(&r->args, "key", r->pool);
        if (!ctx->key)
        {
            return false;
        }
    }

    ctx->proto = HUSTDB_PROTO_BINARY;
    char * proto = ngx_http_get_param_val(&r->args, "proto", r->pool);
    if (proto)
    {
        int tmp = atoi(proto);
        if (HUSTDB_PROTO_JSON == tmp)
        {
            ctx->proto = HUSTDB_PROTO_JSON;
        }
        else if (HUSTDB_PROTO_BINARY == tmp)
        {
            ctx->proto = HUSTDB_PROTO_BINARY;
        }
        else
        {
            return false;
        }
    }

    ctx->tb = ngx_http_get_param_val(&r->args, "tb", r->pool);
    if (has_tb && !ctx->tb)
    {
        return false;
    }

    ctx->ttl = 0;
    char * val = ngx_http_get_param_val(&r->args, "ttl", r->pool);
    if (val)
    {
        ctx->ttl = atoi(val);
    }

    ngx_http_hustdb_ha_main_conf_t * mcf = hustdb_ha_get_module_main_conf(r);
    if (!mcf)
    {
        return false;
    }

    ctx->peer = hustdb_ha_get_writelist(ctx->key);
    if (!ctx->peer)
    {
        return false;
    }

    ctx->error_count = 0;
    ctx->error_peer = NULL;
    ctx->state = STATE_WRITE_MASTER1;

    ngx_bool_t alive = ngx_http_peer_is_alive(ctx->peer->peer);
    if (!alive) // master1
    {
        ++ctx->error_count;
        ctx->error_peer = ctx->peer;

        ctx->peer = ctx->peer->next;
        ctx->state = STATE_WRITE_MASTER2;
        alive = ngx_http_peer_is_alive(ctx->peer->peer);
        if (!alive) // master2
        {
            return false;
        }
    }
    return true;
}
コード例 #5
0
static ngx_bool_t __parse_args(
    ngx_bool_t has_tb,
    ngx_bool_t hash_by_tb,
    ngx_http_request_t *r,
    write_ctx_t * ctx)
{
    ctx->tb = ngx_http_get_param_val(&r->args, "tb", r->pool);
    if (has_tb && !ctx->tb)
    {
        return false;
    }

    ctx->ttl = 0;
    char * val = ngx_http_get_param_val(&r->args, "ttl", r->pool);
    if (val)
    {
        ctx->ttl = atoi(val);
    }

    ctx->score = 0;
    val = ngx_http_get_param_val(&r->args, "score", r->pool);
    if (val)
    {
        char * endptr;
        ctx->score = strtoull(val, &endptr, 10);
    }

    ctx->opt = 0;
    val = ngx_http_get_param_val(&r->args, "opt", r->pool);
    if (val)
    {
        ctx->opt = atoi(val);
    }

    ngx_http_hustdb_ha_main_conf_t * mcf = hustdb_ha_get_module_main_conf(r);
    if (!mcf)
    {
        return false;
    }

    ctx->peer = hustdb_ha_get_writelist(hash_by_tb ? ctx->tb : ctx->key);
    if (!ctx->peer)
    {
        return false;
    }

    ctx->error_count = 0;
    ctx->error_peer = NULL;
    ctx->state = STATE_WRITE_MASTER1;

    ngx_bool_t alive = ngx_http_peer_is_alive(ctx->peer->peer);
    if (!alive) // master1
    {
        ++ctx->error_count;
        ctx->error_peer = ctx->peer;

        ctx->peer = ctx->peer->next;
        ctx->state = STATE_WRITE_MASTER2;
        alive = ngx_http_peer_is_alive(ctx->peer->peer);
        if (!alive) // master2
        {
            return false;
        }
    }
    return true;
}