Dear apr_memcache developers,

I am currently using the apr-util 1.3.X (rev 692755) of apr_memcache
and have noticed that for every active reslist (hard minimum) a
"quit." message is sent to the memcached server before the intended
query. Is there a way to avoid this? This never used to happen on
earlier versions.

An example below:
1. set the apr_memcache_create hard min to 32
2. call apr_memcache_getp on a any "key"
3. watch ngrep spam 32 "quit."'s before the intended query:

ie:
---------------------
######
T 2008/09/09 22:39:45.984160 127.0.0.1:57116 -> 127.0.0.1:15879 [AP]
quit.

#####
T 2008/09/09 22:39:45.984218 127.0.0.1:57115 -> 127.0.0.1:15879 [AP]
quit.

######
T 2008/09/09 22:39:45.984271 127.0.0.1:57114 -> 127.0.0.1:15879 [AP]

quit.
######
T 2008/09/09 22:39:45.984318 127.0.0.1:57113 -> 127.0.0.1:15879 [AP]
quit.
...
etc
...
########
T 2008/09/09 22:39:45.984428 127.0.0.1:57145 -> 127.0.0.1:15879 [AP]
get mykey.

##
T 2008/09/09 22:39:45.984457 127.0.0.1:15879 -> 127.0.0.1:57145 [AP]
VALUE mykey 0 7.
myvalue.
END.
---------------------

I have attached a test program (main.c) showing how I triggered this
issue. It has a hard min of 32, and sends a "set" and
a "get", once every 5 seconds.  This triggers 32 quits every 5 seconds.

Can anyone see what I'm doing wrong here?
I'm trying to maintain a connection pool of 32 connections to our
memcached server to reduce the number of TCP sessions establishments
under high load conditions

Thanks,
Peter Baer
/**
 * test program for apr_memcache
 *
 * gcc -Wall -D_LARGEFILE64_SOURCE -fpic -I/usr/include -I/opt/apr/include/apr-1 -I/opt/apr-util/include/apr-1  -L/opt/apr-util/lib -laprutil-1 -o main main.c
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "apr_memcache.h"

//#define DEFAULT_SLEEP_USEC 100
#define DEFAULT_SLEEP_SEC 5
#define GET_COUNT 10

apr_status_t mc_set(apr_memcache_t *_mc)
{
	apr_status_t rv;

	rv = apr_memcache_set(_mc, "mykey", "myvalue", strlen("myvalue"), 120, 0);
	if (rv != APR_SUCCESS)
		printf("apr_memcache_set error.\n");
	else
		printf("apr_memcache_set successful mc=%p.\n", _mc);

	return rv;
}

apr_status_t mc_get(apr_memcache_t *_mc, apr_pool_t *_p)
{
	apr_status_t rv;
	int len = 0;
	char *s = NULL;

	rv = apr_memcache_getp(_mc, _p, "mykey", &s, &len, 0);
	if (rv != APR_SUCCESS)
		 printf("apr_memcache_get error.\n");
	else
		printf("apr_memcache_getp returned key '%s', len=%d, mc=%p.\n", s, len, _mc);

	return rv;
}

int main(void)
{
	int i;
	char *server_hostname = "localhost";
	int  server_port	  = 15879;
	int  server_conn_min  = 32;
	int  server_conn_smax = 64;
	int  server_conn_max  = 128;
	int  server_conn_ttl  = 120;

	apr_status_t rv;
	apr_memcache_t *mc = NULL;
	apr_memcache_server_t *server = NULL;
	apr_pool_t *pool = NULL;
//	apr_pool_t *get_pool = NULL;

	rv = apr_initialize();
	if (rv != APR_SUCCESS) goto error;
	printf("apr_initialize successful.\n");

	rv = apr_pool_create(&pool, NULL);
	if (rv != APR_SUCCESS) goto error;
	printf("apr_pool_create successful pool=%p.\n", pool);

//	rv = apr_pool_create(&get_pool, NULL);
//	if (rv != APR_SUCCESS) goto error;
//	printf("apr_pool_create successful get_pool=%p.\n", get_pool);

	rv = apr_memcache_create(pool, 1, 0, &mc);
	if (rv != APR_SUCCESS) goto error;
	printf("apr_memcache_create successful mc=%p.\n", mc);

	rv = apr_memcache_server_create(pool, server_hostname, server_port,
			server_conn_min, server_conn_smax, server_conn_max,
			server_conn_ttl, &server);
	if (rv != APR_SUCCESS) goto error;
	printf("apr_memcache_server_create successful server=%p.\n", server);

	rv = apr_memcache_add_server(mc, server);
	if (rv != APR_SUCCESS) goto error;
	printf("apr_memcache_add_server successful.\n");

	sleep(1);

	for(i=0; i<GET_COUNT; i++) {
//		usleep(DEFAULT_SLEEP_USEC);
		sleep(DEFAULT_SLEEP_SEC);
		mc_set(mc);
		mc_get(mc, pool);
	}

	return 1;
error:
	printf("mc api returned non-success, quitting.\n");
	return -1;
}

Reply via email to