if test "$ENABLE_DEBUG" = "yes"
then
CFLAGS="-Wall -ggdb -DMEMCACHED_INTERNAL -DHAVE_DEBUG $CFLAGS"
+ LDFLAGS="-lm"
else
CFLAGS="-Wall -O3 -DMEMCACHED_INTERNAL $CFLAGS"
+ LDFLAGS="-lm"
fi
else
CFLAGS="-Xa -xstrconst -mt -D_FORTEC_ $CFLAGS"
- LDFLAGS="-lsocket -lnsl $LDFLAGS"
+ LDFLAGS="-lm -lsocket -lnsl $LDFLAGS"
DTRACEFLAGS="$DTRACEFLAGS"
fi
Enable the use of the binary protocol. Please note that you cannot toggle
this flag on an open connection.
+=item MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT
+
+Set this value to enable the server be removed after continuous MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT
+times connection failure.
+
=back
=head1 RETURN
uint32_t generate_hash_value(const char *key, size_t key_length, memcached_hash hash_algorithm);
uint32_t generate_hash(memcached_st *ptr, const char *key, size_t key_length);
+memcached_return server_remove(memcached_server_st *st_ptr);
extern uint64_t ntohll(uint64_t);
extern uint64_t htonll(uint64_t);
uint32_t continuum_points_counter;
int32_t snd_timeout;
int32_t rcv_timeout;
+ int32_t server_failure_limit;
};
case MEMCACHED_BEHAVIOR_RCV_TIMEOUT:
ptr->rcv_timeout= (int32_t)data;
break;
+ case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT:
+ ptr->server_failure_limit= (int32_t)data;
+ break;
case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
set_behavior_flag(ptr, MEM_BINARY_PROTOCOL, data);
break;
return ptr->hash;
case MEMCACHED_BEHAVIOR_KETAMA_HASH:
return ptr->hash_continuum;
+ case MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT:
+ return ptr->server_failure_limit;
case MEMCACHED_BEHAVIOR_SORT_HOSTS:
temp_flag= MEM_USE_SORT_HOSTS;
break;
{
struct addrinfo *use;
+ if(ptr->root->server_failure_limit != 0) {
+ if(ptr->server_failure_counter >= ptr->root->server_failure_limit) {
+ server_remove(ptr);
+ }
+ }
/* Old connection junk still is in the structure */
WATCHPOINT_ASSERT(ptr->cursor_active == 0);
{
goto handle_retry;
}
- else if (error != 1)
+ else if (error != 1 || fds[0].revents & POLLERR)
{
ptr->cached_errno= errno;
WATCHPOINT_ERRNO(ptr->cached_errno);
ptr->address_info= NULL;
}
+ if (ptr->root->retry_timeout)
+ {
+ struct timeval next_time;
+
+ gettimeofday(&next_time, NULL);
+ ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
+ }
+ ptr->server_failure_counter+= 1;
return MEMCACHED_ERRNO;
}
else
{
WATCHPOINT_ASSERT(ptr->cursor_active == 0);
+ ptr->server_failure_counter= 0;
return MEMCACHED_SUCCESS;
}
use = use->ai_next;
}
}
- if (ptr->fd == -1)
+ if (ptr->fd == -1) {
+ ptr->server_failure_counter+= 1;
return MEMCACHED_ERRNO; /* The last error should be from connect() */
+ }
+ ptr->server_failure_counter= 0;
return MEMCACHED_SUCCESS; /* The last error should be from connect() */
}
MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,
MEMCACHED_BEHAVIOR_SND_TIMEOUT,
MEMCACHED_BEHAVIOR_RCV_TIMEOUT,
+ MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,
} memcached_behavior;
typedef enum {
return run_distribution(ptr);
}
+memcached_return server_remove(memcached_server_st *st_ptr)
+{
+ int i,index;
+ memcached_st *ptr= st_ptr->root;
+ memcached_server_st *list=ptr->hosts;
+ index= 0;
+ for(i= 0; i< ptr->number_of_hosts; ++i) {
+ if(strncmp(list[i].hostname, st_ptr->hostname, MEMCACHED_MAX_HOST_LENGTH)!=0 || list[i].port != st_ptr->port) {
+ memcpy(list+index, list+i, sizeof(memcached_server_st));
+ index++;
+ } else {
+ ptr->number_of_hosts-=1;
+ }
+ }
+ if(st_ptr->address_info) {
+ freeaddrinfo(st_ptr->address_info);
+ }
+ run_distribution(ptr);
+ return MEMCACHED_SUCCESS;
+}
+
memcached_server_st *memcached_server_list_append(memcached_server_st *ptr,
char *hostname, unsigned int port,
memcached_return *error)
time_t next_retry;
memcached_st *root;
uint64_t limit_maxbytes;
+ uint32_t server_failure_counter;
};
#define memcached_server_count(A) (A)->number_of_hosts