LoginSignup
0
0

More than 5 years have passed since last update.

neoagent1人読書会 その7

Posted at

「その6」で出てきたna_target_server_callbackのもう半分。今回はKVSからのレスポンスを読み込む部分。

コードは「その5」で出てきたna_client_callbackのREADとほぼ同じなのでさくっと終わる。

    if (revents & EV_READ) {

        if (!env->is_extensible_response_buf) {
            if (client->srbufsize >= client->response_bufsize) {
                NA_EVENT_FAIL(NA_ERROR_OUTOF_BUFFER, EV_A, w, client, env);
                return; // request fail
            }
        } else if (client->response_bufsize > env->response_bufsize_max) {
            NA_EVENT_FAIL(NA_ERROR_OUTOF_BUFFER, EV_A, w, client, env);
            return; // request fail
        } else if (client->srbufsize >= client->response_bufsize) {
            size_t es;
            es = (client->response_bufsize - 1) * 2;
            if (es >= env->response_bufsize_max) {
                es = env->response_bufsize_max;
            }
            client->srbuf = (char *)realloc(client->srbuf, es + 1);
            client->response_bufsize = es;
        }

        size = read(tsfd, 
                    client->srbuf + client->srbufsize,
                    client->response_bufsize - client->srbufsize);

        if (size <= 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
                return; // not ready yet
            }
            NA_EVENT_FAIL(NA_ERROR_FAILED_READ, EV_A, w, client, env);
            return; // request fail
        }

        client->srbufsize                += size;
        client->srbuf[client->srbufsize]  = '\0';

        if (client->srbufsize > env->response_bufsize_current_max) {
            env->response_bufsize_current_max = client->srbufsize;
        }
  • srbuf: レスポンスバッファーの先頭を指すポインター
  • srbufsize: レスポンスバッファーのうち実際に使われているバイト数
  • response_bufsize: レスポンスバッファーのバイト数
        if (client->cmd == NA_MEMPROTO_CMD_GET) {
            client->res_cnt = na_memproto_count_response_get(client->srbuf, client->srbufsize);
            if (client->res_cnt >= client->req_cnt) {
                client->event_state = NA_EVENT_STATE_CLIENT_WRITE;
                na_event_switch(EV_A_ w, &client->c_watcher, cfd, EV_WRITE);
                return;
            }

「その5」でも書いたとおり、getだったらmulti getの可能性があるのでリクエスト時のgetのキー数とレスポンスの値の数(END\n\r)を数えて一致したら終了としている。

        } else if (client->srbufsize > 2 &&
                   client->srbuf[client->srbufsize - 2] == '\r' &&
                   client->srbuf[client->srbufsize - 1] == '\n')
        {
            client->event_state = NA_EVENT_STATE_CLIENT_WRITE;
            na_event_switch(EV_A_ w, &client->c_watcher, cfd, EV_WRITE);
        }

ちゃんとリクエストが終了していれば状態をクライアントへの書き出しに変えてイベントウォッチャーを変更して終わり。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0