in feline/src/main/java/com/spotify/feline/FelineTransformer.java [83:122]
static Map<String, Object> onEnter(
@Advice.This() final Object thisObject,
@Advice.Origin("#t") final String typeName,
@Advice.Origin("#m") final String methodName,
@Advice.Origin("#s") final String methodSig) {
final Future<?> future = (Future<?>) thisObject;
boolean state = FelineRuntime.BLOCKED_THREADS.contains(Thread.currentThread().getId());
if (state) {
// Already inside a blocking operation, fast-exit
// and keep state as true (i.e. do nothing)
return Collections.emptyMap();
}
if (future.isDone()) {
// This method call is not actually blocking, so fast-exit
// and keep state as false (i.e. do nothing)
return Collections.emptyMap();
}
final String methodCall = typeName + "." + methodName + methodSig;
FelineRuntime.accept(methodCall);
// Set state to true as to ignore any nested blocked calls, e.g. where one Future delegates
// to another.
// The state must be set after consumers are invoked above. Consumers can throw exceptions,
// in which case we
// must not have modified the state first as it would not be reset in onExit().
FelineRuntime.BLOCKED_THREADS.add(Thread.currentThread().getId());
// Can't use custom classes here, since they won't be visible to classes in standard library
// such as Future.
final Map<String, Object> data = new HashMap<>(2);
data.put("method", methodCall);
data.put("startTimeNanos", System.nanoTime());
return data;
}