Design to generate a Fixed-Rate flow

Hello,

I have a Java client that has to issue requests at fixed rate to a remote server.

The original programmer did it genuilely (and monothreaded):

publicclass Client{

public Client(int rate){

this.delay = ...;//conversion and rounding algorithm omitted;

}

publicvoid sendRequests(){

while (...){

serverProxy.sendRequest(...);

Thread.sleep(delay);

}

}

}

Obviously this doesn't take into account the time it takes to perform the requests themselves, and the jitter of this duration (not fixed as it depends on remote server load,...).

The client was updated to:

publicvoid sendRequests(){

while(...){

long nextTime = System.currentTimeMillis() + delay;

serverProxy.sendRequest(...);

long sleepTime = nextTime - System.currentTimeMillis();

if (sleepTime>0)

Thread.sleep(sleepTime);

}

}

However this doesn't guarantee that the client will be able to respect the rate, even though there is spare CPU: if a request takes too long, the thread won't sleep but the next request is sent late.

Obvisouly we can augment the "scalability" by flinging more threads at work: we could have several instances of Client executed by a bunch of threads, each thread asking a shared object whether it is time to send a new request (code omitted, active wait or awkward wait/notify scheme).

But again at some point, a fixed number of threads will eventually reacha limit (e.g if each request takes 200ms and the number of threads is 100, the client program won't scale above 500 req/s; and if the requests start taking longer...).

Eventually I'd like to make an adaptive scheduler do the job of scaling the threadpool:

I'd write a Scheduler class that triggers aClient.send() method at the fixed rate. The Client methods would no more handle timing, and just issue individual requests.

The Scheduler would use an extensible thread pool, automatically firing a new thread if all existing threads are already busy, or reusing idle threads otherwise.

The limiting factor now, would be the CPU or memory of the client JVM (hopefully the server app will hit its wall before), but not the artificially serial algorithm.

This solution seems awkwardly familiar. I guess it is quite a common algorithmic problem, and possibly such scheduling libraries already exist. Do you know any such library?

Otherwise, do you foresee a problem in me implementing this scheduling?

Thanks in advance.

J.

P.S.: my "client app" is indeed a proprietary throughput test tool, and I'm already looking for standard or off-the-shelf tools instead (see http://forum.java.sun.com/thread.jspa?threadID=737887). But if I have to follow the proprietary route, I need to have this fixed-rate issue solved...

[3685 byte] By [jdupreza] at [2007-10-2 20:31:41]
# 1
Have you considered using Timer and TimerTask?
es5f2000a at 2007-7-13 23:14:50 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

Thanks for replying.

> Have you considered using Timer and TimerTask?

I had dismissed it as a Timer is mono-thread.

I re-read the javadoc though, when I saw your comment. But I confirm:

one Timer instance serializes all tasks in one thread, even using "fixed rate" methods. If delay occurs, and the task exceeds its schedule, the timer thread only tries to catch up by waiting no delay for the next task, possibly resulting in a burst of task executions.

If the delay persists, all requests end up being late, even though the client hardly does any work...

Timer itself is a standard JDK library for solution 2 above, that my colleague coded by hand, good point.

But Timer per se does not fit solution 3 - it does not account for adjusting the thread number to the demand.

Timer could be a building block to schedule wakeups of the Scheduler, but additional code is required to handle a growing thread pool. It doesn't seem such a big deal, but are there pitfalls I have overlooked, or ready-made libraries?

jdupreza at 2007-7-13 23:14:50 > top of Java-index,Other Topics,Patterns & OO Design...