package com.onpositive.gae.profiling.rpc;
import java.util.ArrayList;
import java.util.concurrent.Future;
import com.google.apphosting.api.ApiProxy;
import com.google.apphosting.api.ApiProxy.ApiConfig;
import com.google.apphosting.api.ApiStats;
import com.google.apphosting.api.ApiProxy.ApiProxyException;
import com.google.apphosting.api.ApiProxy.Delegate;
import com.google.apphosting.api.ApiProxy.Environment;
import com.google.apphosting.api.ApiProxy.LogRecord;
import com.onpositive.auth.SessionManager;
import com.onpositive.gae.profiling.rpc.DataStoreCallProcessor.GetInterCeptor;
import com.onpositive.gae.profiling.rpc.DataStoreCallProcessor.PutInterceptor;
import com.onpositive.gae.profiling.rpc.DataStoreCallProcessor.QueryInterceptor;
import com.onpositive.gae.profiling.rpc.DataStoreCallProcessor.RemoveInterCeptor;
import com.onpositive.traps.Profiler;
public class UniveralDelegate implements Delegate<Environment> {
Delegate<Environment> delegate;
public Delegate<Environment> getDelegate() {
return delegate;
}
ArrayList<IRPCCallProcessor> processors = new ArrayList<IRPCCallProcessor>();
public UniveralDelegate() {
}
public UniveralDelegate(Delegate<Environment> delegate) {
super();
this.delegate = delegate;
processors.add(new DataStoreCallProcessor());
processors.add(new MemCacheProcessor());
}
public void log(Environment arg0, LogRecord arg1) {
delegate.log(arg0, arg1);
}
public synchronized byte[] makeSyncCall(Environment arg0, String arg1,
String arg2, byte[] arg3) throws ApiProxyException {
if (Profiler.dumping || SessionManager.isWorking()) {
return delegate.makeSyncCall(arg0, arg1, arg2, arg3);
}
long init = 0;
IRPCCallProcessor proc = getProcessor(arg1);
try {
try {
ApiStats apiStats = ApiStats.get(ApiProxy
.getCurrentEnvironment());
if (apiStats != null) {
init = apiStats.getApiTimeInMegaCycles();
}
} catch (Throwable e) {
e.printStackTrace();
}
if (proc != null) {
proc.preCall(arg2, arg3);
}
byte[] makeSyncCall = delegate.makeSyncCall(arg0, arg1, arg2, arg3);
if (proc != null) {
proc.postCall(arg2, makeSyncCall);
}
return makeSyncCall;
} catch (Throwable e) {
e.printStackTrace();
return null;
} finally {
try {
ApiStats apiStats = ApiStats.get(ApiProxy
.getCurrentEnvironment());
if (apiStats != null) {
long tl = apiStats.getApiTimeInMegaCycles();
int delta = (int) (tl - init);
if (proc != null) {
proc.stat(delta);
}
Profiler.incCPU(delta);
} else {
int delta = 0;
if (proc instanceof DataStoreCallProcessor) {
DataStoreCallProcessor dscp = (DataStoreCallProcessor) proc;
ICallInterceptor ici = dscp.getInterceptors().get(arg2);
if (ici instanceof QueryInterceptor) {
QueryInterceptor qi = (QueryInterceptor) ici;
delta = qi.getCost();
Profiler.incCPU(delta);
//ici.stat(delta);
} else if (ici instanceof RemoveInterCeptor) {
RemoveInterCeptor ri = (RemoveInterCeptor) ici;
delta = ri.getCost();
Profiler.incCPU(delta);
//ici.stat(delta);
} else if (ici instanceof GetInterCeptor) {
GetInterCeptor gi = (GetInterCeptor) ici;
delta = gi.getCost();
Profiler.incCPU(delta);
//gi.stat(delta);
} else if ( ici instanceof PutInterceptor){
PutInterceptor pi = (PutInterceptor)ici;
delta = pi.getCost();
Profiler.incCPU(delta);
}
proc.stat(delta);
}
// Profiler.incCPU((int) (1000));
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
private IRPCCallProcessor getProcessor(String arg1) {
for (IRPCCallProcessor p : processors) {
if (p.getPackage().equals(arg1)) {
return p;
}
}
return null;
}
@SuppressWarnings("unchecked")
public static void install() {
Delegate<Environment> delegate2 = ApiProxy.getDelegate();
if (!(delegate2 instanceof UniveralDelegate)) {
ApiProxy.setDelegate(new UniveralDelegate(delegate2));
}
}
public Future<byte[]> makeAsyncCall(Environment arg0, String arg1,
String arg2, byte[] arg3, ApiConfig arg4) {
if (Profiler.dumping || SessionManager.isWorking()) {
return delegate.makeAsyncCall(arg0, arg1, arg2, arg3, arg4);
}
long init = 0;
IRPCCallProcessor proc = getProcessor(arg1);
try {
try {
ApiStats apiStats = ApiStats.get(ApiProxy
.getCurrentEnvironment());
if (apiStats != null) {
init = apiStats.getApiTimeInMegaCycles();
}
} catch (Throwable e) {
e.printStackTrace();
}
if (proc != null) {
proc.preCall(arg2, arg3);
}
Future<byte[]> makeAsyncCall = delegate.makeAsyncCall(arg0, arg1,
arg2, arg3, arg4);
if (proc != null) {
proc.postCall(arg2, makeAsyncCall.get());
}
return makeAsyncCall;
} catch (Throwable e) {
e.printStackTrace();
return null;
} finally {
try {
ApiStats apiStats = ApiStats.get(ApiProxy
.getCurrentEnvironment());
if (apiStats != null) {
long tl = apiStats.getApiTimeInMegaCycles();
int delta = (int) (tl - init);
if (proc != null) {
proc.stat(delta);
}
Profiler.incCPU(delta);
} else {
int delta = 0;
if (proc instanceof DataStoreCallProcessor) {
DataStoreCallProcessor dscp = (DataStoreCallProcessor) proc;
ICallInterceptor ici = dscp.getInterceptors().get(arg2);
if (ici instanceof QueryInterceptor) {
QueryInterceptor qi = (QueryInterceptor) ici;
delta = qi.getCost();
Profiler.incCPU(delta);
//ici.stat(delta);
} else if (ici instanceof RemoveInterCeptor) {
RemoveInterCeptor ri = (RemoveInterCeptor) ici;
delta = ri.getCost();
Profiler.incCPU(delta);
//ici.stat(delta);
} else if (ici instanceof GetInterCeptor) {
GetInterCeptor gi = (GetInterCeptor) ici;
delta = gi.getCost();
Profiler.incCPU(delta);
//gi.stat(delta);
} else if ( ici instanceof PutInterceptor){
PutInterceptor pi = (PutInterceptor)ici;
delta = pi.getCost();
Profiler.incCPU(delta);
}
proc.stat(delta);
}
// Profiler.incCPU((int) (1000));
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
}