You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2026/08/01 13:23:03 UTC

(skywalking-agent-test-tool) 01/01: fix: drop segments/logs when two services report concurrently for the first time

This is an automated email from the ASF dual-hosted git repository.

wu-sheng pushed a commit to branch fix/concurrent-first-insert
in repository https://gitbox.apache.org/repos/asf/skywalking-agent-test-tool.git

commit a1b5ad9a613e849f4efcdb6e504b472f8d22e51f
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Sat Aug 1 21:22:51 2026 +0800

    fix: drop segments/logs when two services report concurrently for the first time
    
    addSegmentItem and addLogItem look the service name up and then put it
    back as two separate operations. When two agent processes report their
    FIRST data for the same service name concurrently, both threads observe
    null, both construct an item, and the second put overwrites the first —
    the segments already appended to the discarded item are lost while both
    reporters receive HTTP 200. Once the key exists there is no loss, since
    SegmentItem/LogItem hold CopyOnWriteArrayList, so only the very first
    insert per service name is affected.
    
    This surfaced in apache/skywalking-python#409, where a plugin test forks
    a worker: parent and child share one service name and post their first
    segments milliseconds apart, so a segment vanished in roughly 2 of 5 CI
    runs. Reproduced directly against this collector with barrier-
    synchronized first-time POSTs: 15 of 200 rounds lost a segment, and 0 of
    200 once the key had been seeded.
    
    Use computeIfAbsent, which performs the whole get-or-create atomically —
    the pattern MeterItems.addMeter already uses in this package.
    
    Co-Authored-By: Claude Fable 5 <no...@anthropic.com>
---
 .../skywalking/plugin/test/mockcollector/entity/LogItems.java       | 6 +-----
 .../skywalking/plugin/test/mockcollector/entity/SegmentItems.java   | 6 +-----
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/mock-collector/src/main/java/org/apache/skywalking/plugin/test/mockcollector/entity/LogItems.java b/mock-collector/src/main/java/org/apache/skywalking/plugin/test/mockcollector/entity/LogItems.java
index 3321e34..7a62928 100644
--- a/mock-collector/src/main/java/org/apache/skywalking/plugin/test/mockcollector/entity/LogItems.java
+++ b/mock-collector/src/main/java/org/apache/skywalking/plugin/test/mockcollector/entity/LogItems.java
@@ -28,11 +28,7 @@ public class LogItems {
     }
 
     public LogItems addLogItem(String serviceName, Log log) {
-        LogItem logItem = logItems.get(serviceName);
-        if (logItem == null) {
-            logItem = new LogItem(serviceName);
-            logItems.put(serviceName, logItem);
-        }
+        final LogItem logItem = logItems.computeIfAbsent(serviceName, LogItem::new);
         logItem.addLogs(log);
         return this;
     }
diff --git a/mock-collector/src/main/java/org/apache/skywalking/plugin/test/mockcollector/entity/SegmentItems.java b/mock-collector/src/main/java/org/apache/skywalking/plugin/test/mockcollector/entity/SegmentItems.java
index 785f3ef..86bc8ac 100644
--- a/mock-collector/src/main/java/org/apache/skywalking/plugin/test/mockcollector/entity/SegmentItems.java
+++ b/mock-collector/src/main/java/org/apache/skywalking/plugin/test/mockcollector/entity/SegmentItems.java
@@ -28,11 +28,7 @@ public class SegmentItems {
     }
 
     public SegmentItems addSegmentItem(String serviceName, Segment segment) {
-        SegmentItem segmentItem = segmentItems.get(serviceName);
-        if (segmentItem == null) {
-            segmentItem = new SegmentItem(serviceName);
-            segmentItems.put(serviceName, segmentItem);
-        }
+        final SegmentItem segmentItem = segmentItems.computeIfAbsent(serviceName, SegmentItem::new);
         segmentItem.addSegments(segment);
         return this;
     }