/*
* Copyright (c) 2005-2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.synapse.transport.passthru.jmx;
import org.apache.http.protocol.HttpContext;
import org.apache.synapse.transport.nhttp.NhttpConstants;
import org.apache.synapse.transport.passthru.PassThroughConstants;
/**
* Class responsible for collect Latency values per request
*/
public class LatencyCollector {
/**
* Time between response header retrieve time and request written completion time
*/
private long backendLatency = 0;
/**
* complete latency
*/
private long latency = 0;
/**
* Time between req from client read end time and req from client read start time.
*/
private long serverDecodeLatency = 0;
/**
* Time between req to BE write end time and req to BE write start time.
*/
private long clientEncodeLatency = 0;
/**
* Time between res read end time from BE and res read start time form BE
*/
private long clientDecodeLatency = 0;
/**
* Time between res write end from BE and res write start time
*/
private long serverEncodeLatency = 0;
/**
* Time between SeverWorker initiated and run
*/
private long serverWorkerQueuedTime = 0;
/**
* Time between SeverWorker initiated and run
*/
private long clientWorkerQueuedTime = 0;
/**
* Time between SeverWorker run and request to BE write start time
*/
private long serverWorkerLatency = 0;
/**
* Time between ClientWorker run and response to Client write start time.
*/
private long clientWorkerLatency = 0;
public LatencyCollector(HttpContext context, boolean isS2S) {
Object o1, o2, o3, o4;
o1 = context.getAttribute(PassThroughConstants.REQ_ARRIVAL_TIME);
o2 = context.getAttribute(PassThroughConstants.REQ_DEPARTURE_TIME);
if (isS2S) {
o3 = context.getAttribute(PassThroughConstants.RES_HEADER_ARRIVAL_TIME);
o4 = context.getAttribute(PassThroughConstants.RES_TO_CLIENT_WRITE_START_TIME);
} else {
o3 = context.getAttribute(PassThroughConstants.RES_ARRIVAL_TIME);
o4 = context.getAttribute(PassThroughConstants.RES_DEPARTURE_TIME);
}
if (o1 != null && o2 != null && o3 != null && o4 != null) {
long tReqArrival = (Long) o1;
long tReqDeparture = (Long) o2;
long tResArrival = (Long) o3;
long tResDeparture = (Long) o4;
backendLatency = (tResArrival - tReqDeparture);
latency = (tResDeparture - tReqArrival) - backendLatency;
}
o1 = context.getAttribute(PassThroughConstants.REQ_FROM_CLIENT_READ_START_TIME);
o2 = context.getAttribute(PassThroughConstants.REQ_FROM_CLIENT_READ_END_TIME);
if (o1 != null && o2 != null) {
serverDecodeLatency = (Long) o2 - (Long) o1;
}
o1 = context.getAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_START_TIME);
o2 = context.getAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_END_TIME);
if (o1 != null && o2 != null) {
clientEncodeLatency = (Long) o2 - (Long) o1;
}
o1 = context.getAttribute(PassThroughConstants.RES_FROM_BACKEND_READ_START_TIME);
o2 = context.getAttribute(PassThroughConstants.RES_FROM_BACKEND_READ_END_TIME);
if (o1 != null && o2 != null) {
clientDecodeLatency = (Long) o2 - (Long) o1;
}
o1 = context.getAttribute(PassThroughConstants.RES_TO_CLIENT_WRITE_START_TIME);
o2 = context.getAttribute(PassThroughConstants.RES_TO_CLIENT_WRITE_END_TIME);
if (o1 != null && o2 != null) {
serverEncodeLatency = (Long) o2 - (Long) o1;
}
o1 = context.getAttribute(PassThroughConstants.SERVER_WORKER_START_TIME);
o2 = context.getAttribute(PassThroughConstants.SERVER_WORKER_INIT_TIME);
if (o1 != null && o2 != null) {
serverWorkerQueuedTime = (Long) o1 - (Long) o2;
}
o1 = context.getAttribute(PassThroughConstants.CLIENT_WORKER_START_TIME);
o2 = context.getAttribute(PassThroughConstants.CLIENT_WORKER_INIT_TIME);
if (o1 != null && o2 != null) {
clientWorkerQueuedTime = (Long) o1 - (Long) o2;
}
o1 = context.getAttribute(PassThroughConstants.REQ_TO_BACKEND_WRITE_START_TIME);
o2 = context.getAttribute(PassThroughConstants.SERVER_WORKER_START_TIME);
if (o1 != null && o2 != null) {
serverWorkerLatency = (Long) o1 - (Long) o2;
}
o1 = context.getAttribute(PassThroughConstants.RES_TO_CLIENT_WRITE_START_TIME);
o2 = context.getAttribute(PassThroughConstants.CLIENT_WORKER_START_TIME);
if (o1 != null && o2 != null) {
clientWorkerLatency = (Long) o1 - (Long) o2;
}
}
public long getBackendLatency() {
return backendLatency;
}
public long getLatency() {
return latency;
}
public long getServerDecodeLatency() {
return serverDecodeLatency;
}
public long getServerEncodeLatency() {
return serverEncodeLatency;
}
public long getClientEncodeLatency() {
return clientEncodeLatency;
}
public long getClientDecodeLatency() {
return clientDecodeLatency;
}
public long getServerWorkerQueuedTime() {
return serverWorkerQueuedTime;
}
public long getClientWorkerQueuedTime() {
return clientWorkerQueuedTime;
}
public long getServerWorkerLatency() {
return serverWorkerLatency;
}
public long getClientWorkerLatency() {
return clientWorkerLatency;
}
/**
* Clear all timestamps saved.
* @param context HttpContext
*/
public static void clearTimestamps(HttpContext context) {
if (context == null) {
return;
}
context.removeAttribute(NhttpConstants.REQ_ARRIVAL_TIME);
context.removeAttribute(NhttpConstants.REQ_DEPARTURE_TIME);
context.removeAttribute(NhttpConstants.RES_HEADER_ARRIVAL_TIME);
context.removeAttribute(NhttpConstants.RES_TO_CLIENT_WRITE_START_TIME);
context.removeAttribute(NhttpConstants.RES_ARRIVAL_TIME);
context.removeAttribute(NhttpConstants.RES_DEPARTURE_TIME);
context.removeAttribute(NhttpConstants.REQ_FROM_CLIENT_READ_START_TIME);
context.removeAttribute(NhttpConstants.REQ_FROM_CLIENT_READ_END_TIME);
context.removeAttribute(NhttpConstants.REQ_TO_BACKEND_WRITE_START_TIME);
context.removeAttribute(NhttpConstants.REQ_TO_BACKEND_WRITE_END_TIME);
context.removeAttribute(NhttpConstants.RES_FROM_BACKEND_READ_START_TIME);
context.removeAttribute(NhttpConstants.RES_FROM_BACKEND_READ_END_TIME);
context.removeAttribute(NhttpConstants.RES_TO_CLIENT_WRITE_END_TIME);
context.removeAttribute(NhttpConstants.SERVER_WORKER_START_TIME);
context.removeAttribute(NhttpConstants.SERVER_WORKER_INIT_TIME);
context.removeAttribute(NhttpConstants.CLIENT_WORKER_START_TIME);
context.removeAttribute(NhttpConstants.CLIENT_WORKER_INIT_TIME);
}
}