You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
public void activate(TraceContextHolder<?> holder) {
if (logger.isDebugEnabled()) {
logger.debug("Activating {} on thread {}", holder, Thread.currentThread().getId());
}
((Deque)this.activeStack.get()).push(holder);
}
But when retrieving it, the last element of the stack is checked:
ElasticApmTracer.java:
public Transaction currentTransaction() {
TraceContextHolder<?> bottomOfStack = (TraceContextHolder)((Deque)this.activeStack.get()).peekLast();
if (bottomOfStack instanceof Transaction) {
return (Transaction)bottomOfStack;
....................
In the above method, peekLast() returns the oldest transaction instead of newly pushed one.
As multiple methods use Deque::peek(first element) to get active transaction, the logic inside currentTransaction() method should be change to iterate from first to last element:
@Nullable
public Transaction currentTransaction() {
- TraceContextHolder<?> bottomOfStack = (TraceContextHolder)((Deque)this.activeStack.get()).peekLast();
+ TraceContextHolder<?> bottomOfStack = (TraceContextHolder)((Deque)this.activeStack.get()).peek();
if (bottomOfStack instanceof Transaction) {
return (Transaction)bottomOfStack;
} else {
- Iterator it = ((Deque)this.activeStack.get()).descendingIterator();
+ Iterator it = ((Deque)this.activeStack.get()).iterator();
TraceContextHolder context;
do {
elastic-apm-agent-1.9.0
The text was updated successfully, but these errors were encountered:
There shouldn't be multiple nested transactions active on a thread.
At any given time, only a single transaction should be active on the thread at most. Anything nested within it should be a span.
See more in our data model documentation.
Shouldn't this be enforced in code, such as throwing an exception when trying to call transaction.activate() when a transaction already exists?
Also, transaction.activate() javadocs don't mention anything about the behaviour when there is already an active transaction.
Currently, the javadoc is wrong, because ElasticApm.currentTransaction() doesn't get me the activated transaction from code, but instead it returns the root transaction.
Log an error when attempting to activate a transaction while something is already active on the thread
Document that this is invalid
I am not 100% sure about that, as there are many invalid scenarios people can invoke without any possibility for the agent to be aware (eg failing to deactivate or end a transaction/span). The basic requirement for using the API is fully understand the data model and lifecycle of the used objects.
We had a short discussion, agreed on the above.
eyalkoren
changed the title
ElasticApm.currentTransaction() doesn't return active nested transaction
Improve docs and add error log related to illegal activation of transaction
Sep 18, 2019
Using multiple nested transactions,
ElasticApm.currentTransaction()
returns oldest transaction instead of newest created.Activating a transaction transaction.activate() pushes the transaction to the head of the active stack:
ElasticApmTracer.java:
But when retrieving it, the last element of the stack is checked:
ElasticApmTracer.java:
In the above method, peekLast() returns the oldest transaction instead of newly pushed one.
As multiple methods use Deque::peek(first element) to get active transaction, the logic inside currentTransaction() method should be change to iterate from first to last element:
elastic-apm-agent-1.9.0
The text was updated successfully, but these errors were encountered: