Changeset 708
- Timestamp:
- 02/22/08 04:57:41 (8 months ago)
- Files:
-
- trunk/server/devtools/bench_noreply.pl (added)
- trunk/server/doc/protocol.txt (modified) (8 diffs)
- trunk/server/memcached.c (modified) (14 diffs)
- trunk/server/memcached.h (modified) (1 diff)
- trunk/server/t/noreply.t (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/server/doc/protocol.txt
r689 r708 127 127 First, the client sends a command line which looks like this: 128 128 129 <command name> <key> <flags> <exptime> <bytes> [<cas unqiue>]\r\n 130 131 - <command name> is "set", "add", "replace", "append", "prepend", or "cas" 129 <command name> <key> <flags> <exptime> <bytes> [noreply]\r\n 130 cas <key> <flags> <exptime> <bytes> <cas unqiue> [noreply]\r\n 131 132 - <command name> is "set", "add", "replace", "append" or "prepend" 132 133 133 134 "set" means "store this data". … … 175 176 when issuing "cas" updates. 176 177 178 - "noreply" optional parameter instructs the server to not send the 179 reply. NOTE: if the request line is malformed, the server can't 180 parse "noreply" option reliably. In this case it may send the error 181 to the client, and not reading it on the client side will break 182 things. Client should construct only valid requests. 183 177 184 After this line, the client sends the data block: 178 185 … … 246 253 The command "delete" allows for explicit deletion of items: 247 254 248 delete <key> <time>\r\n255 delete <key> [<time>] [noreply]\r\n 249 256 250 257 - <key> is the key of the item the client wishes the server to delete … … 262 269 storage commands with this key will succeed). 263 270 271 - "noreply" optional parameter instructs the server to not send the 272 reply. See the note in Storage commands regarding malformed 273 requests. 274 264 275 The response line to this command can be one of: 265 276 … … 286 297 The client sends the command line: 287 298 288 incr <key> <value> \r\n299 incr <key> <value> [noreply]\r\n 289 300 290 301 or 291 302 292 decr <key> <value> \r\n303 decr <key> <value> [noreply]\r\n 293 304 294 305 - <key> is the key of the item the client wishes to change … … 296 307 - <value> is the amount by which the client wants to increase/decrease 297 308 the item. It is a decimal representation of a 64-bit unsigned integer. 309 310 - "noreply" optional parameter instructs the server to not send the 311 reply. See the note in Storage commands regarding malformed 312 requests. 298 313 299 314 The response will be one of: … … 400 415 401 416 "flush_all" is a command with an optional numeric argument. It always 402 succeeds, and the server sends "OK\r\n" in response. Its effect is to 403 invalidate all existing items immediately (by default) or after the 404 expiration specified. After invalidation none of the items will be returned 405 in response to a retrieval command (unless it's stored again under the 406 same key *after* flush_all has invalidated the items). flush_all doesn't 407 actually free all the memory taken up by existing items; that will 408 happen gradually as new items are stored. The most precise definition 409 of what flush_all does is the following: it causes all items whose 410 update time is earlier than the time at which flush_all was set to be 411 executed to be ignored for retrieval purposes. 417 succeeds, and the server sends "OK\r\n" in response (unless "noreply" 418 is given as the last parameter). Its effect is to invalidate all 419 existing items immediately (by default) or after the expiration 420 specified. After invalidation none of the items will be returned in 421 response to a retrieval command (unless it's stored again under the 422 same key *after* flush_all has invalidated the items). flush_all 423 doesn't actually free all the memory taken up by existing items; that 424 will happen gradually as new items are stored. The most precise 425 definition of what flush_all does is the following: it causes all 426 items whose update time is earlier than the time at which flush_all 427 was set to be executed to be ignored for retrieval purposes. 412 428 413 429 The intent of flush_all with a delay, was that in a setting where you … … 432 448 server. 433 449 434 "verbosity" is a command with a numeric argument. It always 435 succeeds, and the server sends "OK\r\n" in response. Its effect is to 436 set the verbosity level of the logging output. 450 "verbosity" is a command with a numeric argument. It always succeeds, 451 and the server sends "OK\r\n" in response (unless "noreply" is given 452 as the last parameter). Its effect is to set the verbosity level of 453 the logging output. 437 454 438 455 "quit" is a command with no arguments: trunk/server/memcached.c
r707 r708 373 373 c->gen = 0; 374 374 375 c->noreply = false; 376 375 377 event_set(&c->event, sfd, event_flags, event_handler, (void *)c); 376 378 event_base_set(base, &c->event); … … 734 736 assert(c != NULL); 735 737 738 if (c->noreply) { 739 c->noreply = false; 740 conn_set_state(c, conn_read); 741 return; 742 } 743 736 744 if (settings.verbose > 1) 737 745 fprintf(stderr, ">%d %s\n", c->sfd, str); … … 899 907 #define KEY_MAX_LENGTH 250 900 908 901 #define MAX_TOKENS 7909 #define MAX_TOKENS 8 902 910 903 911 /* … … 966 974 } else { 967 975 out_string(c, "SERVER_ERROR out of memory"); 976 } 977 } 978 979 static inline void set_noreply_maybe(conn *c, token_t *tokens, size_t ntokens) 980 { 981 int noreply_index = ntokens - 2; 982 983 /* 984 NOTE: this function is not the first place where we are going to 985 send the reply. We could send it instead from process_command() 986 if the request line has wrong number of tokens. However parsing 987 malformed line for "noreply" option is not reliable anyway, so 988 it can't be helped. 989 */ 990 if (tokens[noreply_index].value 991 && strcmp(tokens[noreply_index].value, "noreply") == 0) { 992 c->noreply = true; 968 993 } 969 994 } … … 1348 1373 assert(c != NULL); 1349 1374 1375 set_noreply_maybe(c, tokens, ntokens); 1376 1350 1377 if (tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) { 1351 1378 out_string(c, "CLIENT_ERROR bad command line format"); … … 1418 1445 1419 1446 assert(c != NULL); 1447 1448 set_noreply_maybe(c, tokens, ntokens); 1420 1449 1421 1450 if(tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) { … … 1515 1544 assert(c != NULL); 1516 1545 1546 set_noreply_maybe(c, tokens, ntokens); 1547 1517 1548 if (settings.managed) { 1518 1549 int bucket = c->bucket; … … 1536 1567 } 1537 1568 1538 if(ntokens == 4) {1569 if(ntokens == (c->noreply ? 5 : 4)) { 1539 1570 exptime = strtol(tokens[2].value, NULL, 10); 1540 1571 … … 1599 1630 assert(c != NULL); 1600 1631 1632 set_noreply_maybe(c, tokens, ntokens); 1633 1601 1634 level = strtoul(tokens[1].value, NULL, 10); 1602 1635 settings.verbose = level > MAX_VERBOSITY_LEVEL ? MAX_VERBOSITY_LEVEL : level; … … 1636 1669 process_get_command(c, tokens, ntokens, false); 1637 1670 1638 } else if ( ntokens == 6&&1671 } else if ((ntokens == 6 || ntokens == 7) && 1639 1672 ((strcmp(tokens[COMMAND_TOKEN].value, "add") == 0 && (comm = NREAD_ADD)) || 1640 1673 (strcmp(tokens[COMMAND_TOKEN].value, "set") == 0 && (comm = NREAD_SET)) || … … 1645 1678 process_update_command(c, tokens, ntokens, comm, false); 1646 1679 1647 } else if ( ntokens == 7&& (strcmp(tokens[COMMAND_TOKEN].value, "cas") == 0 && (comm = NREAD_CAS))) {1680 } else if ((ntokens == 7 || ntokens == 8) && (strcmp(tokens[COMMAND_TOKEN].value, "cas") == 0 && (comm = NREAD_CAS))) { 1648 1681 1649 1682 process_update_command(c, tokens, ntokens, comm, true); 1650 1683 1651 } else if ( ntokens == 4&& (strcmp(tokens[COMMAND_TOKEN].value, "incr") == 0)) {1684 } else if ((ntokens == 4 || ntokens == 5) && (strcmp(tokens[COMMAND_TOKEN].value, "incr") == 0)) { 1652 1685 1653 1686 process_arithmetic_command(c, tokens, ntokens, 1); … … 1657 1690 process_get_command(c, tokens, ntokens, true); 1658 1691 1659 } else if ( ntokens == 4&& (strcmp(tokens[COMMAND_TOKEN].value, "decr") == 0)) {1692 } else if ((ntokens == 4 || ntokens == 5) && (strcmp(tokens[COMMAND_TOKEN].value, "decr") == 0)) { 1660 1693 1661 1694 process_arithmetic_command(c, tokens, ntokens, 0); 1662 1695 1663 } else if (ntokens >= 3 && ntokens <= 4&& (strcmp(tokens[COMMAND_TOKEN].value, "delete") == 0)) {1696 } else if (ntokens >= 3 && ntokens <= 5 && (strcmp(tokens[COMMAND_TOKEN].value, "delete") == 0)) { 1664 1697 1665 1698 process_delete_command(c, tokens, ntokens); … … 1730 1763 process_stat(c, tokens, ntokens); 1731 1764 1732 } else if (ntokens >= 2 && ntokens <= 3&& (strcmp(tokens[COMMAND_TOKEN].value, "flush_all") == 0)) {1765 } else if (ntokens >= 2 && ntokens <= 4 && (strcmp(tokens[COMMAND_TOKEN].value, "flush_all") == 0)) { 1733 1766 time_t exptime = 0; 1734 1767 set_current_time(); 1735 1768 1736 if(ntokens == 2) { 1769 set_noreply_maybe(c, tokens, ntokens); 1770 1771 if(ntokens == (c->noreply ? 3 : 2)) { 1737 1772 settings.oldest_live = current_time - 1; 1738 1773 item_flush_expired(); … … 1799 1834 out_string(c, "CLIENT_ERROR Slab reassignment not supported"); 1800 1835 #endif 1801 } else if ( ntokens == 3&& (strcmp(tokens[COMMAND_TOKEN].value, "verbosity") == 0)) {1836 } else if ((ntokens == 3 || ntokens == 4) && (strcmp(tokens[COMMAND_TOKEN].value, "verbosity") == 0)) { 1802 1837 process_verbosity_command(c, tokens, ntokens); 1803 1838 } else { trunk/server/memcached.h
r701 r708 221 221 a managed instance. -1 (_not_ 0) means invalid. */ 222 222 int gen; /* generation requested for the bucket */ 223 bool noreply; /* True if the reply should not be sent. */ 223 224 conn *next; /* Used for generating a list of conn structures */ 224 225 };
