Skip to content
This repository has been archived by the owner on Sep 18, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Added counting of avg window size and estimated processing time
  • Loading branch information
jjlauer committed May 9, 2011
1 parent c49bf5d commit abf1989
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 28 deletions.
23 changes: 21 additions & 2 deletions src/main/java/com/cloudhopper/smpp/PduAsyncResponse.java
Expand Up @@ -20,7 +20,7 @@
/**
* A container to hold an asynchronous response and include information tracked
* internally by an SmppSession. For example, an instance of this class will
* contain the original request, the response, and the processing time.
* contain the original request, the response, and a few timestamps.
*
* @author joelauer (twitter: @jjlauer or <a href="http://twitter.com/jjlauer" target=window>http://twitter.com/jjlauer</a>)
*/
Expand All @@ -39,7 +39,7 @@ public interface PduAsyncResponse {
public PduResponse getResponse();

/**
* Gets the amount of time required to accept the request into the session's
* Gets the amount of time required to accept the request into the session
* send window (for a free slot to open up).
* @return The amount of time (in ms) to accept the request into the send window
*/
Expand All @@ -51,8 +51,27 @@ public interface PduAsyncResponse {
* went out on the wire till a response was received on the wire. Does not
* include any time required waiting for a slot in the window to become
* available.
* <br><br>
* NOTE: If the window size is > 1, this value can be somewhat misleading.
* The remote endpoint would process X number of requests ahead of this one
* that went out ahead of it in the window. This does represent the total
* response time, but doesn't mean the remote endpoint is this slow at processing
* one request. In cases of high load where the window is always full, the
* windowWaitTime actually represents how fast the remote endpoint is processing
* requests.
* @return The amount of time (in ms) to receive a response from remote endpoint
*/
public long getResponseTime();

/**
* Gets an estimate of the processing time required by the remote endpoint
* to process this request. The value is calculated with the following
* formula: "response time" divided by the "window size" at the time of the
* request.
* @return The amount of estimated time (in ms) to receive a response from
* the remote endpoint just for this request (as opposed to potentially
* this request and all requests ahead of it in the window).
*/
public long getEstimatedProcessingTime();

}
27 changes: 16 additions & 11 deletions src/main/java/com/cloudhopper/smpp/SmppSession.java
Expand Up @@ -203,11 +203,11 @@ public enum Type {
* Attempts to "unbind" the session, waiting up to a specified period of
* milliseconds for an unbind response from the remote endpoint. Regardless of whether
* a proper unbind response was received, the socket/channel is closed.
* @param timeoutInMillis The number of milliseconds to wait until an unbind
* @param timeoutMillis The number of milliseconds to wait until an unbind
* response is received from the SMSC.
* @see #close()
*/
public void unbind(long timeoutInMillis);
public void unbind(long timeoutMillis);

/**
* Destroy a session by ensuring the socket is closed and all
Expand All @@ -226,7 +226,7 @@ public enum Type {
* takes to transmit the actual bytes on the socket, and for the remote
* endpoint to send a response back.
* @param request The request to send to the remote endpoint
* @param timeoutInMillis The number of milliseconds to wait until a valid
* @param timeoutMillis The number of milliseconds to wait until a valid
* response is received.
* @return A valid response to the request
* @throws RecoverablePduException Thrown when a recoverable PDU error occurs.
Expand All @@ -243,7 +243,7 @@ public enum Type {
* @throws InterruptedException The calling thread was interrupted while waiting
* to acquire a lock or write/read the bytes from the socket/channel.
*/
public EnquireLinkResp enquireLink(EnquireLink request, long timeoutInMillis) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException;
public EnquireLinkResp enquireLink(EnquireLink request, long timeoutMillis) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException;

/**
* Synchronously sends a "submit" request to the remote endpoint and
Expand All @@ -252,7 +252,7 @@ public enum Type {
* takes to transmit the actual bytes on the socket, and for the remote
* endpoint to send a response back.
* @param request The request to send to the remote endpoint
* @param timeoutInMillis The number of milliseconds to wait until a valid
* @param timeoutMillis The number of milliseconds to wait until a valid
* response is received.
* @return A valid response to the request
* @throws RecoverablePduException Thrown when a recoverable PDU error occurs.
Expand All @@ -269,7 +269,7 @@ public enum Type {
* @throws InterruptedException The calling thread was interrupted while waiting
* to acquire a lock or write/read the bytes from the socket/channel.
*/
public SubmitSmResp submit(SubmitSm request, long timeoutInMillis) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException;
public SubmitSmResp submit(SubmitSm request, long timeoutMillis) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException;

/**
* Main underlying method for sending a request PDU to the remote endpoint.
Expand All @@ -284,9 +284,14 @@ public enum Type {
* the "fireExpectedPduResponseReceived" method on the session handler.
* Please note that its possible th response PDU really isn't
* the correct PDU we were waiting for, so the caller should verify it.
* The best example is that a "Generic_Nack" could be returned.
* For example it is possible that a "Generic_Nack" could be returned by
* the remote endpoint in response to a PDU.
* @param requestPdu The request PDU to send
* @param timeoutInMillis The length of time to wait for a response PDU
* @param timeoutMillis If synchronous is true, this represents the time to
* wait for a slot to open in the underlying window AND the time to wait
* for a response back from the remote endpoint. If synchronous is false,
* this only represents the time to wait for a slot to open in the
* underlying window.
* @param synchronous True if the calling thread plans on waiting for a
* response on the returned future. False if the calling thread plans
* on discarding the returned future and expects the response PDU to
Expand All @@ -307,7 +312,7 @@ public enum Type {
* @throws InterruptedException The calling thread was interrupted while waiting
* to acquire a lock or write/read the bytes from the socket/channel.
*/
public WindowFuture<Integer,PduRequest,PduResponse> sendRequestPdu(PduRequest request, long timeoutInMillis, boolean synchronous) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException;
public WindowFuture<Integer,PduRequest,PduResponse> sendRequestPdu(PduRequest request, long timeoutMillis, boolean synchronous) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException;

/**
* Main underlying method for sending a response PDU to the remote endpoint.
Expand All @@ -316,9 +321,9 @@ public enum Type {
* @param response The response PDU to send
* @throws RecoverablePduException Thrown when a recoverable PDU error occurs.
* A recoverable PDU error includes the partially decoded PDU in order
* to generate a negative acknowledgement (NACK) response.
* to generate a negative acknowledgment (NACK) response.
* @throws UnrecoverablePduException Thrown when an unrecoverable PDU error
* occurs. This indicates a seriours error occurred and usually indicates
* occurs. This indicates a serious error occurred and usually indicates
* the session should be immediately terminated.
* @throws SmppChannelException Thrown when the underlying socket/channel was
* unable to write the request.
Expand Down
Expand Up @@ -52,6 +52,15 @@ public long getWindowWaitTime() {
public long getResponseTime() {
return future.getAcceptToDoneTime();
}

@Override
public long getEstimatedProcessingTime() {
long responseTime = getResponseTime();
if (responseTime == 0 || future.getWindowSize() == 0) {
return 0;
}
return (responseTime / future.getWindowSize());
}

@Override
public String toString() {
Expand All @@ -60,13 +69,16 @@ public String toString() {
buf.append(HexUtil.toHexString(this.future.getKey()));
buf.append("] windowWaitTime [");
buf.append(getWindowWaitTime());
buf.append("] responseTime [");
buf.append(getWindowWaitTime());
buf.append(" ms] responseTime [");
buf.append(getResponseTime());
buf.append(" ms] estProcessingTime [");
buf.append(getEstimatedProcessingTime());
buf.append(" ms] reqType [");
buf.append(getRequest().getName());
buf.append("] respType [");
buf.append(getResponse().getName());
buf.append("]");
return buf.toString();
}

}
22 changes: 15 additions & 7 deletions src/main/java/com/cloudhopper/smpp/impl/DefaultSmppSession.java
Expand Up @@ -479,7 +479,7 @@ protected PduResponse sendRequestAndGetResponse(PduRequest requestPdu, long time

@SuppressWarnings("unchecked")
@Override
public WindowFuture<Integer,PduRequest,PduResponse> sendRequestPdu(PduRequest pdu, long timeoutInMillis, boolean synchronous) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException {
public WindowFuture<Integer,PduRequest,PduResponse> sendRequestPdu(PduRequest pdu, long timeoutMillis, boolean synchronous) throws RecoverablePduException, UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException {
// assign the next PDU sequence # if its not yet assigned
if (!pdu.hasSequenceNumberAssigned()) {
pdu.setSequenceNumber(this.sequenceNumber.next());
Expand All @@ -490,7 +490,7 @@ public WindowFuture<Integer,PduRequest,PduResponse> sendRequestPdu(PduRequest pd

WindowFuture<Integer,PduRequest,PduResponse> future = null;
try {
future = sendWindow.offer(pdu.getSequenceNumber(), pdu, timeoutInMillis, configuration.getRequestExpiryTimeout(), synchronous);
future = sendWindow.offer(pdu.getSequenceNumber(), pdu, timeoutMillis, configuration.getRequestExpiryTimeout(), synchronous);
} catch (DuplicateKeyException e) {
throw new UnrecoverablePduException(e.getMessage(), e);
} catch (OfferTimeoutException e) {
Expand Down Expand Up @@ -576,7 +576,7 @@ public void firePduReceived(Pdu pdu) {
if (responsePdu != null) {
try {
long responseTime = System.currentTimeMillis() - startTime;
this.countSendResponsePdu(responsePdu, responseTime);
this.countSendResponsePdu(responsePdu, responseTime, responseTime);

this.sendResponsePdu(responsePdu);
} catch (Exception e) {
Expand All @@ -593,7 +593,7 @@ public void firePduReceived(Pdu pdu) {
WindowFuture<Integer,PduRequest,PduResponse> future = this.sendWindow.complete(receivedPduSeqNum, responsePdu);
if (future != null) {
logger.trace("Found a future in the window for seqNum [{}]", receivedPduSeqNum);
this.countReceiveResponsePdu(responsePdu, future.getOfferToAcceptTime(), future.getAcceptToDoneTime());
this.countReceiveResponsePdu(responsePdu, future.getOfferToAcceptTime(), future.getAcceptToDoneTime(), (future.getAcceptToDoneTime() / future.getWindowSize()));

// if this isn't null, we found a match to a request
int callerStateHint = future.getCallerStateHint();
Expand All @@ -613,7 +613,7 @@ public void firePduReceived(Pdu pdu) {
this.sessionHandler.fireUnexpectedPduResponseReceived(responsePdu);
}
} else {
this.countReceiveResponsePdu(responsePdu, 0, 0);
this.countReceiveResponsePdu(responsePdu, 0, 0, 0);

// original request either expired OR was completely unexpected
this.sessionHandler.fireUnexpectedPduResponseReceived(responsePdu);
Expand Down Expand Up @@ -708,7 +708,7 @@ private void countSendRequestPdu(PduRequest pdu) {
}
}

private void countSendResponsePdu(PduResponse pdu, long responseTime) {
private void countSendResponsePdu(PduResponse pdu, long responseTime, long estimatedProcessingTime) {
if (this.counters == null) {
return; // noop
}
Expand All @@ -718,21 +718,25 @@ private void countSendResponsePdu(PduResponse pdu, long responseTime) {
case SmppConstants.CMD_ID_SUBMIT_SM_RESP:
this.counters.getRxSubmitSM().incrementResponseAndGet();
this.counters.getRxSubmitSM().addRequestResponseTimeAndGet(responseTime);
this.counters.getRxSubmitSM().addRequestEstimatedProcessingTimeAndGet(estimatedProcessingTime);
this.counters.getRxSubmitSM().getResponseCommandStatusCounter().incrementAndGet(pdu.getCommandStatus());
break;
case SmppConstants.CMD_ID_DELIVER_SM_RESP:
this.counters.getRxDeliverSM().incrementResponseAndGet();
this.counters.getRxDeliverSM().addRequestResponseTimeAndGet(responseTime);
this.counters.getRxDeliverSM().addRequestEstimatedProcessingTimeAndGet(estimatedProcessingTime);
this.counters.getRxDeliverSM().getResponseCommandStatusCounter().incrementAndGet(pdu.getCommandStatus());
break;
case SmppConstants.CMD_ID_DATA_SM_RESP:
this.counters.getRxDataSM().incrementResponseAndGet();
this.counters.getRxDataSM().addRequestResponseTimeAndGet(responseTime);
this.counters.getRxDataSM().addRequestEstimatedProcessingTimeAndGet(estimatedProcessingTime);
this.counters.getRxDataSM().getResponseCommandStatusCounter().incrementAndGet(pdu.getCommandStatus());
break;
case SmppConstants.CMD_ID_ENQUIRE_LINK_RESP:
this.counters.getRxEnquireLink().incrementResponseAndGet();
this.counters.getRxEnquireLink().addRequestResponseTimeAndGet(responseTime);
this.counters.getRxEnquireLink().addRequestEstimatedProcessingTimeAndGet(estimatedProcessingTime);
this.counters.getRxEnquireLink().getResponseCommandStatusCounter().incrementAndGet(pdu.getCommandStatus());
break;
}
Expand Down Expand Up @@ -785,7 +789,7 @@ private void countReceiveRequestPdu(PduRequest pdu) {
}
}

private void countReceiveResponsePdu(PduResponse pdu, long waitTime, long responseTime) {
private void countReceiveResponsePdu(PduResponse pdu, long waitTime, long responseTime, long estimatedProcessingTime) {
if (this.counters == null) {
return; // noop
}
Expand All @@ -796,24 +800,28 @@ private void countReceiveResponsePdu(PduResponse pdu, long waitTime, long respon
this.counters.getTxSubmitSM().incrementResponseAndGet();
this.counters.getTxSubmitSM().addRequestWaitTimeAndGet(waitTime);
this.counters.getTxSubmitSM().addRequestResponseTimeAndGet(responseTime);
this.counters.getTxSubmitSM().addRequestEstimatedProcessingTimeAndGet(estimatedProcessingTime);
this.counters.getTxSubmitSM().getResponseCommandStatusCounter().incrementAndGet(pdu.getCommandStatus());
break;
case SmppConstants.CMD_ID_DELIVER_SM_RESP:
this.counters.getTxDeliverSM().incrementResponseAndGet();
this.counters.getTxDeliverSM().addRequestWaitTimeAndGet(waitTime);
this.counters.getTxDeliverSM().addRequestResponseTimeAndGet(responseTime);
this.counters.getTxDeliverSM().addRequestEstimatedProcessingTimeAndGet(estimatedProcessingTime);
this.counters.getTxDeliverSM().getResponseCommandStatusCounter().incrementAndGet(pdu.getCommandStatus());
break;
case SmppConstants.CMD_ID_DATA_SM_RESP:
this.counters.getTxDataSM().incrementResponseAndGet();
this.counters.getTxDataSM().addRequestWaitTimeAndGet(waitTime);
this.counters.getTxDataSM().addRequestResponseTimeAndGet(responseTime);
this.counters.getTxDataSM().addRequestEstimatedProcessingTimeAndGet(estimatedProcessingTime);
this.counters.getTxDataSM().getResponseCommandStatusCounter().incrementAndGet(pdu.getCommandStatus());
break;
case SmppConstants.CMD_ID_ENQUIRE_LINK_RESP:
this.counters.getTxEnquireLink().incrementResponseAndGet();
this.counters.getTxEnquireLink().addRequestWaitTimeAndGet(waitTime);
this.counters.getTxEnquireLink().addRequestResponseTimeAndGet(responseTime);
this.counters.getTxEnquireLink().addRequestEstimatedProcessingTimeAndGet(estimatedProcessingTime);
this.counters.getTxEnquireLink().getResponseCommandStatusCounter().incrementAndGet(pdu.getCommandStatus());
break;
}
Expand Down

0 comments on commit abf1989

Please sign in to comment.