#include "internal.h"
int
lcb_should_retry(lcb_settings *settings, mc_PACKET *pkt, lcb_error_t err)
{
lcb_RETRYCMDOPTS policy;
lcb_RETRYMODEOPTS mode;
protocol_binary_request_header hdr;
mcreq_read_hdr(pkt, &hdr);
switch (hdr.request.opcode) {
case PROTOCOL_BINARY_CMD_GET_REPLICA:
case PROTOCOL_BINARY_CMD_FLUSH:
case PROTOCOL_BINARY_CMD_OBSERVE:
case PROTOCOL_BINARY_CMD_OBSERVE_SEQNO:
case PROTOCOL_BINARY_CMD_STAT:
case PROTOCOL_BINARY_CMD_VERBOSITY:
case PROTOCOL_BINARY_CMD_VERSION:
return 0;
}
if (err == LCB_ETIMEDOUT || err == LCB_MAP_CHANGED) {
return 0;
} else if (err == LCB_AUTH_ERROR) {
return 1;
} else if (err == LCB_NOT_MY_VBUCKET) {
mode = LCB_RETRY_ON_VBMAPERR;
} else if (err == LCB_MAX_ERROR) {
mode = LCB_RETRY_ON_TOPOCHANGE;
} else if (LCB_EIFNET(err)) {
mode = LCB_RETRY_ON_SOCKERR;
} else {
return 0;
}
policy = settings->retry[mode];
if (policy == LCB_RETRY_CMDS_ALL) {
return 1;
} else if (policy == LCB_RETRY_CMDS_NONE) {
return 0;
}
switch (hdr.request.opcode) {
case PROTOCOL_BINARY_CMD_GET:
case PROTOCOL_BINARY_CMD_GETKQ:
case PROTOCOL_BINARY_CMD_SUBDOC_GET:
case PROTOCOL_BINARY_CMD_SUBDOC_EXISTS:
case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_LOOKUP:
return policy & LCB_RETRY_CMDS_GET;
case PROTOCOL_BINARY_CMD_ADD:
return policy & LCB_RETRY_CMDS_SAFE;
case PROTOCOL_BINARY_CMD_SET:
case PROTOCOL_BINARY_CMD_REPLACE:
case PROTOCOL_BINARY_CMD_APPEND:
case PROTOCOL_BINARY_CMD_PREPEND:
case PROTOCOL_BINARY_CMD_DELETE:
case PROTOCOL_BINARY_CMD_UNLOCK_KEY:
case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_ADD_UNIQUE:
case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_PUSH_FIRST:
case PROTOCOL_BINARY_CMD_SUBDOC_ARRAY_PUSH_LAST:
case PROTOCOL_BINARY_CMD_SUBDOC_COUNTER:
case PROTOCOL_BINARY_CMD_SUBDOC_DELETE:
case PROTOCOL_BINARY_CMD_SUBDOC_DICT_UPSERT:
case PROTOCOL_BINARY_CMD_SUBDOC_REPLACE:
case PROTOCOL_BINARY_CMD_SUBDOC_DICT_ADD:
case PROTOCOL_BINARY_CMD_SUBDOC_MULTI_MUTATION:
if (hdr.request.cas) {
return policy & LCB_RETRY_CMDS_SAFE;
} else {
return 0;
}
case PROTOCOL_BINARY_CMD_INCREMENT:
case PROTOCOL_BINARY_CMD_DECREMENT:
case PROTOCOL_BINARY_CMD_TOUCH:
case PROTOCOL_BINARY_CMD_GAT:
case PROTOCOL_BINARY_CMD_GET_LOCKED:
default:
return 0;
}
}