-
Notifications
You must be signed in to change notification settings - Fork 174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make twemcache deal with partial request value #124
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel as this change could use a different type of test, with a client sending messages instead of the unit tests we've been writing.
test/storage/slab/check_slab.c
Outdated
@@ -23,6 +23,7 @@ test_setup(void) | |||
{ | |||
option_load_default((struct option *)&options, OPTION_CARDINALITY(options)); | |||
slab_setup(&options, &metrics); | |||
printf("foo\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uhm, probably not meant to be commited
test/storage/slab/check_slab.c
Outdated
ck_assert_int_eq(it->klen, sizeof(KEY) - 1); | ||
ck_assert_int_eq(it->dataflag, dataflag); | ||
ck_assert_int_eq(it->vlen, val.len); | ||
ck_assert_msg(strspn(item_data(it), "A") == val.len, "item_data contains wrong value %.*s", it->vlen, item_data(it)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think item_data(it)
is null terminated
test/storage/slab/check_slab.c
Outdated
key = str2bstr(KEY); | ||
|
||
vlen = 1000 * KiB; | ||
val.len = vlen / 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel the test would be better if val.len
was not exactly the half of vlen
as it will make both sides to be the same length coincidentally, and an error may be missed because of it.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
test/storage/slab/check_slab.c
Outdated
free(val.data); | ||
ck_assert_msg(!it->is_linked, "item linked by mistake"); | ||
ck_assert_int_eq(it->vlen, vlen); | ||
ck_assert_msg(strspn(item_data(it) + vlen - val.len, "B") == val.len, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add an assertion on the first part of the item_data to make sure it was not modified?
} | ||
END_TEST | ||
|
||
START_TEST(test_evict_refcount) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this test exactly the same as the one above?
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/server/twemcache/data/process.c
Outdated
item_delete(key); | ||
status = item_insert(key, &(req->vstr), req->flag, time_reltime(req->expiry)); | ||
if ((it = item_get(key)) != NULL) { | ||
status =_generic_set(req, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing space after =
src/server/twemcache/data/process.c
Outdated
@@ -262,8 +288,7 @@ _process_cas(struct response *rsp, struct request *req) | |||
rsp->type = RSP_EXISTS; | |||
INCR(process_metrics, cas_exists); | |||
} else { | |||
item_delete(key); | |||
status = item_insert(key, &(req->vstr), req->flag, time_reltime(req->expiry)); | |||
status =_generic_set(req, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing space after =
src/server/twemcache/data/process.c
Outdated
@@ -207,7 +233,7 @@ _process_add(struct response *rsp, struct request *req) | |||
rsp->type = RSP_NOT_STORED; | |||
INCR(process_metrics, add_notstored); | |||
} else { | |||
status = item_insert(key, &(req->vstr), req->flag, time_reltime(req->expiry)); | |||
status =_generic_set(req, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing space after =
src/server/twemcache/data/process.c
Outdated
item_delete(key); | ||
status = item_insert(key, &(req->vstr), req->flag, time_reltime(req->expiry)); | ||
|
||
status =_generic_set(req, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing space after =
src/protocol/data/memcache/request.c
Outdated
@@ -39,6 +39,10 @@ request_reset(struct request *req) | |||
req->delta = 0; | |||
req->vcas = 0; | |||
|
|||
req->partial = false; /* only set to true when partial value received */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having a rstate
that may be REQ_PARTIAL
this sees either redundant, or at least confusing... looking at the change I can see partial being set to false
only when rstate
going from REQ_PARTIAL
to REQ_PARSED
and set to true
only when rstate is set to REQ_PARTIAL
... isn't then this boolean redundant?
2d6869f
to
8a05490
Compare
This comment was marked as spam.
This comment was marked as spam.
We can have test dependencies that are not used for the binaries, in fact we should already have that for libcheck, and not require them for building the binaries. I believe it should be on the same repo, as they may need to get updated with code changes and that seems to be the common practice in other projects (e.g.: node projects have a Given this specific use case for partial requests, I don't believe any memcached client will expose an appropriated interface for the test we need, which is unfortunate, so I believe any scripting language will be good enough. |
src/protocol/data/memcache/parse.c
Outdated
buf, buf_rsize(buf), vlen + CRLF_LEN); | ||
|
||
return PARSE_EUNFIN; | ||
if (rsize < nbyte + CRLF_LEN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since rsize
and nbyte
do not change before checking the value of complete
, can you move this branch below, get rid of complete
and use an else
instead of if (complete)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if I made myself clear, something like this:
diff --git a/src/protocol/data/memcache/parse.c b/src/protocol/data/memcache/parse.c
index cf3c06b..66cff18 100644
--- a/src/protocol/data/memcache/parse.c
+++ b/src/protocol/data/memcache/parse.c
@@ -277,21 +277,18 @@ _parse_val(struct bstring *val, struct buf *buf, uint32_t nbyte)
{
parse_rstatus_t status;
uint32_t rsize = buf_rsize(buf);
- bool complete = true;
log_verb("parsing val (string) at %p", buf->rpos);
- if (rsize < nbyte + CRLF_LEN) {
- complete = false;
- status = PARSE_EUNFIN;
- }
-
val->len = MIN(nbyte, rsize);
val->data = (val->len > 0) ? buf->rpos : NULL;
buf->rpos += val->len;
- /* verify CRLF */
- if (complete) { /* _try_crlf cannot return EUNFIN in this case */
+
+ if (rsize < nbyte + CRLF_LEN) {
+ status = PARSE_EUNFIN;
+ } else {
+ /* _try_crlf cannot return EUNFIN in this case */
status = _try_crlf(buf, buf->rpos);
if (status == PARSE_OK) {
buf->rpos += CRLF_LEN;
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
buf->rpos - old_rpos); | ||
/* return and start from beginning next time */ | ||
request_reset(req); | ||
buf->rpos = old_rpos; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, but I think we're missing a break;
here? otherwise it will enter the next if
(as status
is not PARSE_OK
) and it will set the rstate
to REQ_PARSED
.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
key = array_first(req->keys); | ||
if (item_get(key) != NULL) { | ||
it = (struct item *)req->reserved; | ||
key = (struct bstring){it->klen, item_key(it)}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if item_reserve
failed in _put
, req->reserved
will be null, and all this code will fail; check for status != PUT_ERROR
earlier
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/server/twemcache/data/process.c
Outdated
item_delete(key); | ||
status = item_insert(key, &(req->vstr), req->flag, time_reltime(req->expiry)); | ||
if (status == ITEM_OK) { | ||
it = (struct item *)req->reserved; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here ^^
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/server/twemcache/data/process.c
Outdated
key = array_first(req->keys); | ||
it = item_get(key); | ||
if (it == NULL) { | ||
it = (struct item *)req->reserved; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^^
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/server/twemcache/data/process.c
Outdated
item_delete(key); | ||
status = item_insert(key, &nval, dataflag, it->expire_at); | ||
status = item_reserve(&it, key, &nval, nval.len, dataflag, | ||
it->expire_at); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check for status before inserting?
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
8a05490
to
868d074
Compare
src/server/twemcache/data/process.c
Outdated
_error_rsp(rsp, istatus); | ||
INCR(process_metrics, set_ex); | ||
INCR(process_metrics, cas_ex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cas_ex
?
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
src/server/twemcache/data/process.c
Outdated
@@ -242,23 +245,25 @@ _process_set(struct response *rsp, struct request *req) | |||
struct item *it; | |||
struct bstring key; | |||
|
|||
status = _put(&istatus, req); | |||
status = _put(&istatus, req, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are you deleting the existing item if set
fails? If I understand this correctly, failing to set key
to value2
will delete existing value1
, is that so?
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, a couple of minor comments
I'd love an integration test 😄 and it'd be nice if someone else can review it, as this change is quite large
int ret; | ||
struct bstring key = str2bstr(KEY); | ||
struct bstring val1 = str2bstr(VAL1); | ||
struct bstring val2 = str2bstr(VAL2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer if VAL1
and VAL2
were not the same length as it can hide some arithmetic bug like subtracting remaining number of bytes instead of received bytes
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
#undef EXPIRY | ||
#undef FLAG | ||
#undef VAL | ||
#undef KEY |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EXPIRY
, FLAG
, VAL
and KEY
were not defined, remove undef
This comment was marked as spam.
This comment was marked as spam.
Sorry, something went wrong.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
This comment was marked as spam.
efca3df
to
7261897
Compare
7261897
to
37fe4e5
Compare
remove install instructions; get rid of cmake warning
4a3a0fd Merge pull request twitter#124 from thinkingfish/remove_install d2964bd Merge pull request twitter#122 from paegun/fix-ubuntu-test-linkage 481597c remove install instructions (will re-add later); get rid of cmake warning 74d9db8 reordered pthread dependency to follow check, the earliest dependent lib. d5c2fec fixed test linkage for ubuntu, tested on 14.04. added support for test-coverage.sh to use xdg-open rather than open when present, ie on ubuntu. git-subtree-dir: deps/ccommon git-subtree-split: 4a3a0fd
This is the first diff to address issue #122
Subsequent diff will add more unit tests, as well as handle partial value when writing responses (when wbuf is full)