Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.apache.synapse;

import java.util.List;

/**
* Implementations of this interface holds the runtime state information of important checkpoints
* of the mediation flow.
Expand Down Expand Up @@ -77,4 +79,28 @@ public interface ContinuationState {
*/
public void removeLeafChild();

/**
* Get the statistics parent index stored in this continuation state.
* @return The parent index for statistics tracing
*/
public Integer getStatisticsParentIndex();

/**
* Set the statistics parent index for this continuation state.
* @param statisticsParentIndex The parent index to store
*/
public void setStatisticsParentIndex(Integer statisticsParentIndex);

/**
* Get the statistics parent list stored in this continuation state.
* @return The parent list for statistics tracing
*/
public List<Integer> getStatisticsParentList();

/**
* Set the statistics parent list for this continuation state.
* @param statisticsParentList The parent list to store
*/
public void setStatisticsParentList(List<Integer> statisticsParentList);

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ protected static boolean isEndpointOrInboundEndpoint(StatisticDataUnit statistic
statisticDataUnit.getComponentType().equals(ComponentType.INBOUNDENDPOINT);
}

protected static boolean isSequence(StatisticDataUnit statisticDataUnit) {
return statisticDataUnit.getComponentType().equals(ComponentType.SEQUENCE);
}

protected static boolean isFlowContinuableMediator(StatisticDataUnit statisticDataUnit) {
return statisticDataUnit.isFlowContinuableMediator();
}
Expand All @@ -49,4 +53,14 @@ protected static boolean isSendMediator(StatisticDataUnit statisticDataUnit) {
return ComponentType.MEDIATOR.equals(statisticDataUnit.getComponentType()) &&
"sendmediator".equalsIgnoreCase(statisticDataUnit.getComponentName());
}

protected static boolean isCloneMediator(StatisticDataUnit statisticDataUnit) {
return ComponentType.MEDIATOR.equals(statisticDataUnit.getComponentType()) &&
"CloneMediator".equalsIgnoreCase(statisticDataUnit.getComponentName());
}

protected static boolean isScatterGatherMediator(StatisticDataUnit statisticDataUnit) {
return ComponentType.MEDIATOR.equals(statisticDataUnit.getComponentType()) &&
"ScatterGatherMediator".equalsIgnoreCase(statisticDataUnit.getComponentName());
}
Comment on lines +57 to +65
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the AbstractParentResolver file
find . -name "AbstractParentResolver.java" -type f 2>/dev/null | head -5

Repository: wso2/wso2-synapse

Length of output: 209


🏁 Script executed:

#!/bin/bash
# Read the AbstractParentResolver file to see existing predicates
cat ./modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/parentresolving/AbstractParentResolver.java

Repository: wso2/wso2-synapse

Length of output: 3077


🏁 Script executed:

#!/bin/bash
# Find mediator implementations
find . -name "CloneMediator.java" -o -name "ScatterGatherMediator.java" -o -name "ForeachMediator.java" -o -name "CallMediator.java" -o -name "SendMediator.java" 2>/dev/null | head -10

Repository: wso2/wso2-synapse

Length of output: 318


🏁 Script executed:

#!/bin/bash
# Search for ForeachMediator and ScatterGatherMediator more broadly
find . -type f -name "*Foreach*.java" -o -type f -name "*ScatterGather*.java" 2>/dev/null

Repository: wso2/wso2-synapse

Length of output: 432


🏁 Script executed:

#!/bin/bash
# Check what getComponentName() or getType() returns for these mediators
# Start with CallMediator
echo "=== CallMediator ==="
grep -n "getComponentName\|getType" ./modules/core/src/main/java/org/apache/synapse/mediators/builtin/CallMediator.java | head -20

echo -e "\n=== SendMediator ==="
grep -n "getComponentName\|getType" ./modules/core/src/main/java/org/apache/synapse/mediators/builtin/SendMediator.java | head -20

echo -e "\n=== CloneMediator ==="
grep -n "getComponentName\|getType" ./modules/core/src/main/java/org/apache/synapse/mediators/eip/splitter/CloneMediator.java | head -20

Repository: wso2/wso2-synapse

Length of output: 214


🏁 Script executed:

#!/bin/bash
# Search for getComponentName in the codebase to understand how it's implemented
echo "=== Searching for getComponentName implementation ==="
rg -n "getComponentName|getMediatorName" --type java | head -30

Repository: wso2/wso2-synapse

Length of output: 6369


🏁 Script executed:

#!/bin/bash
# Look for getMediatorName() implementation in AbstractMediator
echo "=== Searching for getMediatorName implementation ==="
rg -A 3 "getMediatorName()" ./modules/core/src/main/java/org/apache/synapse/mediators/AbstractMediator.java | head -30

# Also look for how component names are set in statistics
echo -e "\n=== Searching for componentName assignment in StatisticDataUnit ==="
rg -B 2 -A 2 "componentName\s*=" ./modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/data/raw/StatisticDataUnit.java | head -40

Repository: wso2/wso2-synapse

Length of output: 1726


🏁 Script executed:

#!/bin/bash
# Find ForeachMediator implementation to verify the naming
find . -type f -name "*ForeachMediator.java" -o -name "*IterateMediator.java" 2>/dev/null | head -10

# Also check what the actual class names are for the mediators in question
echo -e "\n=== Check actual class names ==="
rg "^public class (Call|Send|Clone|Foreach|Iterate|ScatterGather)" --type java | grep -i mediator

Repository: wso2/wso2-synapse

Length of output: 5297


🏁 Script executed:

#!/bin/bash
# Check what IterateMediator class name is (for "ForeachMediator" reference)
echo "=== IterateMediator class definition ==="
grep "^public class IterateMediator" ./modules/core/src/main/java/org/apache/synapse/mediators/eip/splitter/IterateMediator.java

# Check ScatterGather actual class name
echo -e "\n=== ScatterGather class definition ==="
grep "^public class ScatterGather" ./modules/core/src/main/java/org/apache/synapse/mediators/v2/ScatterGather.java

# Look for any references to "ForeachMediator" in the codebase
echo -e "\n=== Search for ForeachMediator references ==="
rg "ForeachMediator|foreachmediator" --type java modules/core/src/main/java/org/apache/synapse/mediators/ 2>/dev/null | head -20

Repository: wso2/wso2-synapse

Length of output: 378


🏁 Script executed:

#!/bin/bash
# Let's verify by checking what getMediatorName() would return for each class
# We know it extracts the simple class name
# Test with a simple Python verification
python3 << 'EOF'
# Given that getMediatorName() returns the simple class name from the full qualified name:
# org.apache.synapse.mediators.builtin.CallMediator -> CallMediator
# org.apache.synapse.mediators.builtin.SendMediator -> SendMediator
# org.apache.synapse.mediators.eip.splitter.CloneMediator -> CloneMediator
# org.apache.synapse.mediators.eip.splitter.IterateMediator -> IterateMediator
# org.apache.synapse.mediators.v2.ScatterGather -> ScatterGather

actual_names = {
    "CallMediator": "CallMediator",
    "SendMediator": "SendMediator", 
    "CloneMediator": "CloneMediator",
    "IterateMediator": "IterateMediator",
    "ScatterGather": "ScatterGather"
}

predicates = {
    "isCallMediator": "callmediator",
    "isSendMediator": "sendmediator",
    "isForeachMediator": "foreachmediator",
    "isCloneMediator": "CloneMediator",
    "isScatterGatherMediator": "ScatterGatherMediator"
}

print("Comparison of actual class names vs strings in predicates:")
print("=" * 80)
for pred_name, pred_string in predicates.items():
    matching_class = None
    for class_name in actual_names:
        if class_name.lower() == pred_string.lower():
            matching_class = class_name
            break
    
    if matching_class:
        actual_value = actual_names[matching_class]
        match = "✓ MATCHES (case-insensitive)" if actual_value.lower() == pred_string.lower() else "✗ MISMATCH"
        print(f"{pred_name:30s} | Predicate: '{pred_string:25s}' | Actual class: {actual_value:20s} | {match}")
    else:
        print(f"{pred_name:30s} | Predicate: '{pred_string:25s}' | Actual class: {'NOT FOUND':20s} | ✗ NO MATCH")

print("\n" + "=" * 80)
print("Issue Summary:")
print("- isCallMediator checks 'callmediator' but CallMediator.getMediatorName() returns 'CallMediator'")
print("- isSendMediator checks 'sendmediator' but SendMediator.getMediatorName() returns 'SendMediator'")
print("- isForeachMediator checks 'foreachmediator' but the class is IterateMediator (not ForeachMediator)")
print("- isCloneMediator checks 'CloneMediator' ✓ matches actual")
print("- isScatterGatherMediator checks 'ScatterGatherMediator' but actual class is ScatterGather")
EOF

Repository: wso2/wso2-synapse

Length of output: 147


🏁 Script executed:

#!/bin/bash
# Simple check: let's look at the actual tests or usage to see what component names are expected
echo "=== Check test files for expected component names ==="
rg -A 5 -B 5 "callmediator|sendmediator|foreachmediator" --type java modules/core/src/test/ 2>/dev/null | head -50

echo -e "\n=== Check for ScatterGather usage ==="
rg "ScatterGather|scattergather" --type java modules/core/src/main/java/org/apache/synapse/aspects/ 2>/dev/null | head -20

Repository: wso2/wso2-synapse

Length of output: 2155


🏁 Script executed:

#!/bin/bash
# Let's verify by looking for where component names are actually set
# Check OpenEventCollector or similar to see how component names are collected
echo "=== Looking for where component names are set in statistics collection ==="
rg -B 3 -A 3 "getMediatorName()" ./modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/collectors/ | head -60

echo -e "\n=== Check if there's any name transformation happening ==="
rg -A 5 "reportChildEntryEvent\|reportFlowContinuableEvent" ./modules/core/src/main/java/org/apache/synapse/mediators/AbstractMediator.java | head -40

Repository: wso2/wso2-synapse

Length of output: 195


🏁 Script executed:

#!/bin/bash
# Let's check the actual mediator implementations directly
echo "=== CloneMediator.java - check for getMediatorName override ==="
rg -A 2 "getMediatorName" ./modules/core/src/main/java/org/apache/synapse/mediators/eip/splitter/CloneMediator.java

echo -e "\n=== CallMediator.java - check for getMediatorName override ==="
rg -A 2 "getMediatorName" ./modules/core/src/main/java/org/apache/synapse/mediators/builtin/CallMediator.java

echo -e "\n=== ScatterGather.java - check for getMediatorName override ==="
rg -A 2 "getMediatorName" ./modules/core/src/main/java/org/apache/synapse/mediators/v2/ScatterGather.java

echo -e "\n=== SendMediator.java - check for getMediatorName override ==="
rg -A 2 "getMediatorName" ./modules/core/src/main/java/org/apache/synapse/mediators/builtin/SendMediator.java

Repository: wso2/wso2-synapse

Length of output: 2277


🏁 Script executed:

#!/bin/bash
# Now let's verify our findings by checking what isForeachMediator actually matches
echo "=== Verify: Does 'foreachmediator' match 'IterateMediator'? ==="
cat > /tmp/test_case.java << 'EOF'
public class Test {
    public static void main(String[] args) {
        String actual = "IterateMediator";
        String predicate = "foreachmediator";
        System.out.println("Does '" + predicate + "' equalsIgnoreCase '" + actual + "'? " + 
                          predicate.equalsIgnoreCase(actual));
        
        String actual2 = "ScatterGather";
        String predicate2 = "ScatterGatherMediator";
        System.out.println("Does '" + predicate2 + "' equalsIgnoreCase '" + actual2 + "'? " + 
                          predicate2.equalsIgnoreCase(actual2));
    }
}
EOF
cd /tmp && javac test_case.java && java Test

Repository: wso2/wso2-synapse

Length of output: 188


🏁 Script executed:

#!/bin/bash
# Let's do a final comprehensive check
echo "=== Final verification: All mediator class names and their getMediatorName() output ==="
echo ""
echo "Based on the code analysis:"
echo "getMediatorName() in AbstractMediator extracts simple class name from full qualified name"
echo ""
echo "Class Name              -> getMediatorName() output"
echo "=====================================================";
echo "CallMediator            -> CallMediator"
echo "SendMediator            -> SendMediator"
echo "CloneMediator           -> CloneMediator"
echo "IterateMediator         -> IterateMediator"
echo "ScatterGather           -> ScatterGather"
echo ""
echo "=== Predicates in AbstractParentResolver ==="
echo ""
echo "Predicate               | String checked          | Actual class name   | Match?"
echo "=====================================================================";
echo "isForeachMediator       | 'foreachmediator'       | IterateMediator     | NO!"
echo "isCallMediator          | 'callmediator'          | CallMediator        | YES (case-insensitive)"
echo "isSendMediator          | 'sendmediator'          | SendMediator        | YES (case-insensitive)"
echo "isCloneMediator         | 'CloneMediator'         | CloneMediator       | YES"
echo "isScatterGatherMediator | 'ScatterGatherMediator' | ScatterGather       | NO!"
echo ""
echo "=== Check if there's a ScatterGatherMediator class anywhere ==="
find . -type f -name "*ScatterGatherMediator.java" 2>/dev/null

Repository: wso2/wso2-synapse

Length of output: 1270


Fix component name strings to match actual mediator class names.

The predicates have inconsistencies with the actual component names returned by getMediatorName() (which extracts the simple class name from the full qualified name):

  • isForeachMediator checks "foreachmediator" but the actual class is IterateMediator — should be "iteratemediator"
  • isScatterGatherMediator checks "ScatterGatherMediator" but the actual class is ScatterGather — should be "scattergather"
  • isCloneMediator correctly checks "CloneMediator" matching the actual class
  • Existing predicates (isCallMediator, isSendMediator) use lowercase ("callmediator", "sendmediator") which work due to equalsIgnoreCase() but don't match the actual class names exactly

For consistency and correctness, either:

  1. Update the new predicates to follow the existing lowercase convention: "cloneMediator""clonemediator", "ScatterGatherMediator""scattergather"
  2. Or fix all predicates to match the actual class name casing: "CallMediator", "SendMediator", "CloneMediator", "IterateMediator", "ScatterGather"
🤖 Prompt for AI Agents
In
modules/core/src/main/java/org/apache/synapse/aspects/flow/statistics/tracing/opentelemetry/management/parentresolving/AbstractParentResolver.java
around lines 57 to 65, the component name string checks are inconsistent with
the actual mediator simple class names and the project's existing lowercase
convention; update the predicate string literals so they consistently match the
simple class names in lowercase (e.g., change the foreach/iterate check to
"iteratemediator", change the scatter/gather check to "scattergather", and
ensure clone uses "clonemediator") while keeping equalsIgnoreCase() to preserve
case-insensitive comparison.

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public static SpanWrapper resolveParent(StatisticDataUnit child, SpanStore spanS
*/
return LatestActiveParentResolver.resolveParentForEndpointOrInboundEndpoint(spanStore);
}

if (TracingUtils.isAnonymousSequence(parent.getStatisticDataUnit()) ||
TracingUtils.isAnonymousSequence(child)) {
if (isFlowContinuableMediator(parent.getStatisticDataUnit()) ||
Expand All @@ -60,6 +61,12 @@ public static SpanWrapper resolveParent(StatisticDataUnit child, SpanStore spanS
}
return getLatestEligibleParent(spanStore);
}

// Special handling for sequences executing in cloned/parallel contexts
// (e.g., inside Clone mediator or Scatter Gather mediator)
if (isSequence(child)) {
return findRecentCloneOrScatterGatherMediator(spanStore);
}
}
return null;
}
Expand All @@ -84,4 +91,25 @@ private static SpanWrapper getLatestEligibleParent(SpanStore spanStore) {
}
return null;
}
}

/**
* Finds the most recent Clone or Scatter Gather mediator in the span store.
* This is used when sequences are executing inside cloned/parallel contexts.
* @param spanStore Span store object.
* @return The most recent Clone or Scatter Gather mediator span wrapper, or null if not found.
*/
private static SpanWrapper findRecentCloneOrScatterGatherMediator(SpanStore spanStore) {
Object[] spanWrapperKeys = spanStore.getSpanWrappers().keySet().toArray();
for (int i = spanWrapperKeys.length - 1; i >= 0; i--) {
String key = (String)spanWrapperKeys[i];
SpanWrapper spanWrapper = spanStore.getSpanWrapper(key);
if (spanWrapper != null && spanWrapper.getStatisticDataUnit() != null) {
StatisticDataUnit unit = spanWrapper.getStatisticDataUnit();
if (isCloneMediator(unit) || isScatterGatherMediator(unit)) {
return spanWrapper;
}
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.apache.synapse.continuation;

import org.apache.synapse.ContinuationState;
import java.util.List;

public abstract class AbstractContinuationState implements ContinuationState {

Expand All @@ -30,6 +31,16 @@ public abstract class AbstractContinuationState implements ContinuationState {
*/
private ContinuationState childContState = null;

/**
* Statistics parent index for tracing context preservation across async boundaries.
*/
private Integer statisticsParentIndex;

/**
* Statistics parent list for tracing context preservation across async boundaries.
*/
private List<Integer> statisticsParentList;

/**
* Get the child ContinuationState
* @return child ContinuationState
Expand Down Expand Up @@ -115,4 +126,36 @@ public void removeLeafChild() {
}
}

/**
* Get the statistics parent index stored in this continuation state.
* @return The parent index for statistics tracing
*/
public Integer getStatisticsParentIndex() {
return statisticsParentIndex;
}

/**
* Set the statistics parent index for this continuation state.
* @param statisticsParentIndex The parent index to store
*/
public void setStatisticsParentIndex(Integer statisticsParentIndex) {
this.statisticsParentIndex = statisticsParentIndex;
}

/**
* Get the statistics parent list stored in this continuation state.
* @return The parent list for statistics tracing
*/
public List<Integer> getStatisticsParentList() {
return statisticsParentList;
}

/**
* Set the statistics parent list for this continuation state.
* @param statisticsParentList The parent list to store
*/
public void setStatisticsParentList(List<Integer> statisticsParentList) {
this.statisticsParentList = statisticsParentList;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.synapse.aspects.flow.statistics.collectors.RuntimeStatisticCollector;
import org.apache.synapse.aspects.flow.statistics.tracing.opentelemetry.management.OpenTelemetryManager;
import org.apache.synapse.aspects.flow.statistics.tracing.opentelemetry.OpenTelemetryManagerHolder;
import org.apache.synapse.aspects.flow.statistics.util.StatisticsConstants;
import org.apache.synapse.core.axis2.ProxyService;
import org.apache.synapse.inbound.InboundEndpoint;
import org.apache.synapse.mediators.MediatorFaultHandler;
Expand Down Expand Up @@ -120,7 +121,21 @@ public static void updateSeqContinuationState(MessageContext synCtx, int positio
if (synCtx.isContinuationEnabled()) {
ContinuationState seqContState = ContinuationStackManager.peakContinuationStateStack(synCtx);
if (seqContState != null) {
seqContState.getLeafChild().setPosition(position);
ContinuationState leafChild = seqContState.getLeafChild();
leafChild.setPosition(position);

// Save statistics parent context with the continuation state for tracing
if (RuntimeStatisticCollector.isStatisticsEnabled()) {
Integer parentIndex = (Integer) synCtx.getProperty(
StatisticsConstants.MEDIATION_FLOW_STATISTICS_PARENT_INDEX);
java.util.List<Integer> parentList = (java.util.List<Integer>) synCtx.getProperty(
StatisticsConstants.MEDIATION_FLOW_STATISTICS_PARENT_LIST);

// Store parent context in the continuation state
leafChild.setStatisticsParentIndex(parentIndex);
leafChild.setStatisticsParentList(parentList != null ?
new java.util.LinkedList<>(parentList) : null);
}
} else {
// Ideally we should not get here.
log.warn("Continuation Stack is empty. Probably due to a configuration issue");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.apache.synapse.aspects.flow.statistics.collectors.CloseEventCollector;
import org.apache.synapse.aspects.flow.statistics.collectors.OpenEventCollector;
import org.apache.synapse.aspects.flow.statistics.collectors.RuntimeStatisticCollector;
import org.apache.synapse.aspects.flow.statistics.util.StatisticsConstants;
import org.apache.synapse.aspects.flow.statistics.store.MessageDataStore;
import org.apache.synapse.carbonext.TenantInfoConfigurator;
import org.apache.synapse.commons.json.JsonUtil;
Expand Down Expand Up @@ -841,8 +842,34 @@ private boolean mediateFromContinuationStateStack(MessageContext synCtx) {
}
}

// Store parent context before opening continuation events (they will be consumed)
Integer savedParentIndex = null;
List<Integer> savedParentList = null;

if (RuntimeStatisticCollector.isStatisticsEnabled()) {
// Get parent context from continuation state before opening events
if (!synCtx.getContinuationStateStack().isEmpty()) {
ContinuationState contState = synCtx.getContinuationStateStack().peek();
if (contState != null) {
// Get the leaf child where parent context was stored
ContinuationState leafState = contState.getLeafChild();
if (leafState != null) {
savedParentIndex = leafState.getStatisticsParentIndex();
savedParentList = leafState.getStatisticsParentList();
}
}
}
OpenEventCollector.openContinuationEvents(synCtx);

// Restore parent context AFTER opening continuation events
if (savedParentIndex != null) {
synCtx.setProperty(StatisticsConstants.MEDIATION_FLOW_STATISTICS_PARENT_INDEX,
savedParentIndex);
}
if (savedParentList != null) {
synCtx.setProperty(StatisticsConstants.MEDIATION_FLOW_STATISTICS_PARENT_LIST,
new java.util.LinkedList<>(savedParentList));
}
}

//First push fault handlers for first continuation state.
Expand Down Expand Up @@ -870,6 +897,25 @@ private boolean mediateFromContinuationStateStack(MessageContext synCtx) {
}

private void callMediatorPostMediate(MessageContext response) {
// Restore statistics parent context from continuation state for blocking calls
if (RuntimeStatisticCollector.isStatisticsEnabled() &&
!response.getContinuationStateStack().isEmpty()) {
ContinuationState contState = response.getContinuationStateStack().peek();
if (contState != null) {
Integer savedParentIndex = contState.getStatisticsParentIndex();
List<Integer> savedParentList = contState.getStatisticsParentList();

if (savedParentIndex != null) {
response.setProperty(StatisticsConstants.MEDIATION_FLOW_STATISTICS_PARENT_INDEX,
savedParentIndex);
}
if (savedParentList != null) {
response.setProperty(StatisticsConstants.MEDIATION_FLOW_STATISTICS_PARENT_LIST,
new java.util.LinkedList<>(savedParentList));
}
}
}

Target targetForInboundPayload = (Target) response.getProperty(TARGET_FOR_INBOUND_PAYLOAD);
String sourceMessageType = (String) response.getProperty(SOURCE_MESSAGE_TYPE);
String originalMessageType = (String) response.getProperty(ORIGINAL_MESSAGE_TYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ public boolean mediate(MessageContext synCtx, ContinuationState continuationStat
boolean result;
int subBranch = ((ReliantContinuationState) continuationState).getSubBranch();
boolean isStatisticsEnabled = RuntimeStatisticCollector.isStatisticsEnabled();
Integer statisticReportingIndex = null;

if (isStatisticsEnabled) {
statisticReportingIndex = reportOpenStatistics(synCtx, false);
}

if (subBranch == 0) {
// Default flow
TemplateMediator templateMediator = (TemplateMediator) synCtx.getSequenceTemplate(targetTemplate);
Expand Down Expand Up @@ -332,6 +338,11 @@ public boolean mediate(MessageContext synCtx, ContinuationState continuationStat
prefetchInvoke.reportCloseStatistics(synCtx, null);
}
}

if (isStatisticsEnabled && statisticReportingIndex != null) {
reportCloseStatistics(synCtx, statisticReportingIndex);
}

return result;
}

Expand Down
Loading