Пример #1
0
/**
 start a new, potentially, rate-limited run
 */
void
mkrunner()
{
    runner *run = calloc(1, sizeof(runner));
    run->id = runid++;

    if(run == nil)
        panic("calloc");

    mkhttp(run);

    if(qps_enabled()) {
        run->tv.tv_sec = 0;
        run->tv.tv_usec = 1000000/params.qps + USEC_FUDGE;

        if(run->tv.tv_usec < 1)
            run->tv.tv_usec = 1;

        evtimer_set(&run->ev, runnercb, run);
        evtimer_add(&run->ev, &run->tv);
        debug("mkrunner(): evtimer_add(&run->ev, &run->tv);\n");
    } else {
        // skip the timers and just loop as fast as possible
        runnercb(0, 0, run);
    }
}
Пример #2
0
void
timeoutcb(int fd, short what, void *arg)
{
	struct request *req =(struct request *)arg;

	/* re-establish the connection */
	evhttp_connection_free(req->evcon);
	req->evcon = mkhttp();

	complete(Timeout, req);
}
Пример #3
0
void
timeoutcb(int fd, short what, void *arg)
{
    runner *run = (runner *)arg;
    debug("timeoutcb()\n");

    /* re-establish the connection */
    evhttp_connection_free(run->evcon);
    mkhttp(run);

    complete(Timeout, run);
}
Пример #4
0
void
complete(int how, struct request *req)
{
	struct timeval now, diff;
	int i, total;
	long milliseconds;

	evtimer_del(&req->timeoutev);

	switch(how){
	case Success:
		gettimeofday(&now, nil);
		timersub(&now, &req->starttv, &diff);
		milliseconds = diff.tv_sec * 1000 + diff.tv_usec / 1000;
		for(i=0; params.buckets[i]<milliseconds &&
		    params.buckets[i]!=0; i++);
		counts.counters[i]++;
		counts.successes++;
		break;
	case Error:
		counts.errors++;
		break;
	case Timeout:
		counts.timeouts++;
		break;
	}

	total =
	    counts.successes + counts.errors + 
	    counts.timeouts /*+ counts.closes*/;
	/* enqueue the next one */
	if(params.count<0 || total<params.count){
		if(params.rpc<0 || params.rpc>req->evcon_reqno){
			dispatch(req->evcon, req->evcon_reqno + 1);
		}else{
			evhttp_connection_free(req->evcon);
			dispatch(mkhttp(), 1);
		}
	}else{
		/* We'll count this as a close. I guess that's ok. */
		evhttp_connection_free(req->evcon);
		if(--params.concurrency == 0){
			evtimer_del(&reportev);
			reportcb(0, 0, nil);  /* issue a last report */
		}
	}

	
	free(req);
}
Пример #5
0
void
complete(int how, runner *run)
{
    struct request *req = run->req;
    save_request(how, run);

    evtimer_del(&req->timeoutev);
    debug("complete(): evtimer_del(&req->timeoutev);\n");

    /* enqueue the next one */
    if(params.count<0 || counts.conns<params.count){
        // re-scheduling is handled by the callback
        if(!qps_enabled()){
            if(!rpc_enabled() || req->evcon_reqno<params.rpc){
                dispatch(run, req->evcon_reqno + 1);
            }else{
                // re-establish the connection
                evhttp_connection_free(run->evcon);
                mkhttp(run);
                dispatch(run, 1);
            }
        }
    }else{
        /* We'll count this as a close. I guess that's ok. */
        evhttp_connection_free(req->evcon);
        if(--params.concurrency == 0){
            evtimer_del(&reportev);
            debug("last call to reportcb\n");
            reportcb(0, 0, nil);  /* issue a last report */
        }
    }

    if(!qps_enabled())
      // FIXME possible memory leak
      free(req);
}
Пример #6
0
int
main(int argc, char **argv)
{
	int ch, i, nprocs = 1, is_parent = 1, port, *sockets, fds[2];
	pid_t pid;
	char *sp, *ap, *host, *cmd = argv[0];
	struct hostent *he;

	/* Defaults */
	params.count = -1;
	params.rpc = -1;
	params.concurrency = 1;
	memset(params.buckets, 0, sizeof(params.buckets));
	params.buckets[0] = 1;
	params.buckets[1] = 10;
	params.buckets[2] = 100;
	params.nbuckets = 4;

	memset(&counts, 0, sizeof(counts));

	while((ch = getopt(argc, argv, "c:b:n:p:r:i:hf:")) != -1){
		switch(ch){
		case 'b':
			sp = optarg;

			memset(params.buckets, 0, sizeof(params.buckets));

			for(i=0; i<MAX_BUCKETS && (ap=strsep(&sp, ",")) != nil; i++)
				params.buckets[i] = atoi(ap);

			params.nbuckets = i;

			if(params.buckets[0] == 0)
				panic("first bucket must be >0\n");

			for(i=1; params.buckets[i]!=0; i++){
				if(params.buckets[i]<params.buckets[i-1])
					panic("invalid bucket specification!\n");
			}
			break;

		case 'c':
			params.concurrency = atoi(optarg);
			break;

		case 'n':
			params.count = atoi(optarg);
			break;

		case 'p':
			nprocs = atoi(optarg);
			break;

		case 'i':
			reporttv.tv_sec = atoi(optarg);
			break;

		case 'r':
			params.rpc = atoi(optarg);
			break;

		case 'h':
			usage(cmd);
			break;

		case 'f':
			read_config(optarg);
			break;

		}
	}

	argc -= optind;
	argv += optind;

	host = "127.0.0.1";
	port = 80;
	switch(argc){
	case 2:
		port = atoi(argv[1]);
	case 1:
		host = argv[0];
	case 0:
		break;
	default:
		panic("only 0 or 1(host port) pair are allowed\n");
	}

	http_hostname = host;
	http_port = port;
	if(snprintf(http_hosthdr, sizeof(http_hosthdr), "%s:%d", host, port) > sizeof(http_hosthdr))
		panic("snprintf");

	for(i = 0; params.buckets[i] != 0; i++)
		request_timeout = params.buckets[i];

	if(params.count > 0)
		params.count /= nprocs;

#if 0
	event_init();
	dispatch(mkhttp(), 1);
	event_dispatch(); exit(0);
#endif

	fprintf(stderr, "# params: c=%d p=%d n=%d r=%d\n",
	    params.concurrency, nprocs, params.count, params.rpc);

	fprintf(stderr, "# ts\t\terrors\ttimeout\tcloses\t");
	for(i=0; params.buckets[i]!=0; i++)
		fprintf(stderr, "<%d\t", params.buckets[i]);

	fprintf(stderr, ">=%d\thz\n", params.buckets[i - 1]);

	if((sockets = calloc(nprocs + 1, sizeof(int))) == nil)
		panic("malloc\n");

	sockets[nprocs] = -1;

	for(i=0; i<nprocs; i++){
		if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0){
			perror("socketpair");
			exit(1);
		}

		sockets[i] = fds[0];

		if((pid = fork()) < 0){
			kill(0, SIGINT);
			perror("fork");
			exit(1);
		}else if(pid != 0){
			close(fds[1]);
			continue;
		}

		is_parent = 0;

		evbase = event_init();

		/* Set up output. */
		if(dup2(fds[1], STDOUT_FILENO) < 0){
			perror("dup2");
			exit(1);
		}

		close(fds[1]);

		for(i=0; i<params.concurrency; i++)
			dispatch(mkhttp(), 1);

		evtimer_set(&reportev, reportcb, nil);
		evtimer_add(&reportev, &reporttv);

		event_dispatch();

		break;
	}

	if(is_parent)
		parentd(nprocs, sockets);

	return(0);
}
Пример #7
0
void
dispatchcb(int fd, short what, void *arg)
{
	free(arg);
	dispatch(mkhttp(), 1);
}