A client that sends commands to a server. This is different than {@link CommandClient} implementations because itmaintains a queue of outgoing command requests which allows it to emit them asynchronously when appropriate Requests can be sent {@link #sendSynch(Command) synchronously} or{@link #sendAsynch(Command,CommandResponseCallback) asynchronously}.
You have to tell this class when it is allowed to send commands (see {@link #startSending()} and when it should nolonger be sending commands (see {@link #stopSending(boolean)}. You are still allowed to queue commands via {@link #sendAsynch(Command,CommandResponseCallback)} even if this object was told to stop sending. The queue willsimply grow until its full or until this object is told to start sending again. This starting and stopping allows you to cleanly switch the server that this object sends commands to - see {@link #setRemoteCommunicator(RemoteCommunicator)}. See {@link ServerPollingThread} as a helper thread that can beused to automatically start and stop this sender when the server comes up or goes down.
This sender object supports two different kinds of throttling - queue throttling and send throttling. The {@link ClientCommandSenderConfiguration configuration} defines the parameters for both - you canenable one, both or none. They work independently.
Queue throttling affects all commands sent asynchronously and only asynchronously. The queue where the asynchronous commands are placed can be throttled in such a way that only X commands can be taken from the queue in any T time period (called the 'burst period', specified in milliseconds). This means that if X+n commands are queued, only X will be dequeued and sent in the first burst period of T milliseconds. After that T millisecond burst period passes, the rest of the commands are dequeued and sent. Note that if n > X, then only the first X will be dequeued until the second burst period passes. The cycle continues until queue throttling is disabled or this sender is told to {@link #stopSending(boolean) stop sending messages altogether}.
Send throttling affects commands sent both asynchronously and synchronously. Unlike queue throttling, an individual command can be configured to ignore send throttling. That is to say, some commands can be sent immediately even if send throttling is enabled. Send throttling works by allowing X commands to be sent - once that limit of X commands is reached, a forced 'quiet period' begins, with that quiet period defined in milliseconds. No commands can be sent until the quiet time period expires. Once the quiet period ends, another X commands can be sent before another quiet period must start. The cycle continues until sent throttling is disabled or this sender is told to stop sending messages altogether.
Queue throttling and send throttling can be enabled simultaneously. Queue throttling occurs first, and then send throttling second. That is to say, a command to be sent must pass through the queue throttle first and then must pass the send throttle in order for the command to actually be sent.
@author John Mazzitelli