Permalink
Browse files

bug 1792 - handle OPAQUE_IGNORE_REPLY for both ascii and binary clients

This commit is with regards to handling ascii and binary clients concurrently.

A client on one protocol (binary), might be assigned to use a
downstream connection that was previously servicing another protocol
(ascii).  The a2b protocol handler would use a special opaque magic
value OPAQUE_IGNORE_REPLY to signal that a given binary response
should be ignored.  This OPAQUE_IGNORE_REPLAY was used to map ascii
"noreply" commands to binary quiet commands.

This commit allows the b2b (binary-to-binary) codepath to handle any
OPAQUE_IGNORE_REPLY which it encounters.  These responses might be
sitting on the connection due to a2b (ascii-to-binary) usage.

cproxy_binary_ignore_reply()

Change-Id: Ie0232c3c72268d352d2ed553283b2abab6db7874
Reviewed-on: http://review.northscale.com/1229
Reviewed-by: Aliaksey Kandratsenka <alkondratenko@gmail.com>
Tested-by: Steve Yen <steve.yen@gmail.com>
  • Loading branch information...
1 parent 6f43f30 commit 6c1acee564f37f9768fd25b9d49effb8cf566691 @steveyen steveyen committed Jul 18, 2010
Showing with 44 additions and 30 deletions.
  1. +10 −0 cproxy.h
  2. +3 −30 cproxy_protocol_a2b.c
  3. +27 −0 cproxy_protocol_b.c
  4. +4 −0 cproxy_protocol_b2b.c
View
@@ -540,6 +540,16 @@ bool b2b_forward_item_vbucket(conn *uc, downstream *d, item *it,
// ---------------------------------------------------------------
+// Magic opaque value that tells us to eat a binary quiet command
+// response. That is, do not send the response up to the ascii client
+// which originally made its request with noreply.
+//
+#define OPAQUE_IGNORE_REPLY 0x0411F00D
+
+bool cproxy_binary_ignore_reply(conn *c, protocol_binary_response_header *header, item *it);
+
+// ---------------------------------------------------------------
+
proxy_main *cproxy_gen_proxy_main(proxy_behavior behavior,
int nthreads, enum_proxy_conf_type conf_type);
View
@@ -22,12 +22,6 @@ static protocol_binary_request_noop req_noop = {
#define KEY_TOKEN 1
#define MAX_TOKENS 9
-// Magic opaque value that tells us to eat a binary quiet command
-// response. That is, do not send the response up to the ascii client
-// which originally made its request with noreply.
-//
-#define OPAQUE_IGNORE_REPLY 0x0411F00D
-
// A2B means ascii-to-binary (or, ascii upstream and binary downstream).
//
struct A2BSpec {
@@ -670,33 +664,12 @@ void a2b_process_downstream_response(conn *c) {
//
c->item = NULL;
- conn *uc = d->upstream_conn;
-
- if (c->noreply &&
- OPAQUE_IGNORE_REPLY == ntohl(header->response.opaque)) {
- // Handle when the client sent an ascii noreply command,
- // and we now need to eat the binary error responses.
- // So, drop the current response (should be an error response)
- // and go to read the next response message.
- //
- if (settings.verbose > 2) {
- fprintf(stderr,
- "<%d cproxy_process_a2b_downstream_response OPAQUE_IGNORE_REPLY, "
- "cmd: %x, status: %x, ignoring reply\n",
- c->sfd, header->response.opcode, header->response.status);
- }
-
- assert(header->response.status != PROTOCOL_BINARY_RESPONSE_SUCCESS);
-
- conn_set_state(c, conn_new_cmd);
-
- if (it != NULL) {
- item_remove(it);
- }
-
+ if (cproxy_binary_ignore_reply(c, header, it)) {
return;
}
+ conn *uc = d->upstream_conn;
+
// Handle not-my-vbucket error response.
//
if (status == PROTOCOL_BINARY_RESPONSE_NOT_MY_VBUCKET) {
View
@@ -273,3 +273,30 @@ void cproxy_dump_header(int prefix, char *bb) {
fprintf(stderr, "\n");
}
}
+
+bool cproxy_binary_ignore_reply(conn *c, protocol_binary_response_header *header, item *it) {
+ if (c->noreply &&
+ OPAQUE_IGNORE_REPLY == ntohl(header->response.opaque)) {
+ // Handle when the client sent an ascii noreply command,
+ // and we now need to eat the binary error responses.
+ // So, drop the current response (should be an error response)
+ // and go to read the next response message.
+ //
+ if (settings.verbose > 2) {
+ fprintf(stderr,
+ "<%d cproxy_process_a2b_downstream_response OPAQUE_IGNORE_REPLY, "
+ "cmd: %x, status: %x, ignoring reply\n",
+ c->sfd, header->response.opcode, header->response.status);
+ }
+
+ conn_set_state(c, conn_new_cmd);
+
+ if (it != NULL) {
+ item_remove(it);
+ }
+
+ return true;
+ }
+
+ return false;
+}
View
@@ -357,6 +357,10 @@ void cproxy_process_b2b_downstream_nread(conn *c) {
assert(it != NULL);
assert(it->refcount == 1);
+ if (cproxy_binary_ignore_reply(c, header, it)) {
+ return;
+ }
+
if (c->noreply) {
conn_set_state(c, conn_new_cmd);
} else {

0 comments on commit 6c1acee

Please sign in to comment.