This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch camel-3.20.x in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-3.20.x by this push: new 29fff127138 CAMEL-18844: Fix event console performance degration on high concurrent load due to internal locking. 29fff127138 is described below commit 29fff127138a97a74ac6c76b089e33932fb7fb80 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Wed Dec 28 18:03:44 2022 +0100 CAMEL-18844: Fix event console performance degration on high concurrent load due to internal locking. --- .../apache/camel/impl/console/EventConsole.java | 70 ++++++++++------------ 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/EventConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/EventConsole.java index 00504fa8c72..4f1c9bed9ad 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/EventConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/EventConsole.java @@ -19,6 +19,7 @@ package org.apache.camel.impl.console; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.camel.spi.CamelEvent; import org.apache.camel.spi.Configurer; @@ -37,11 +38,11 @@ public class EventConsole extends AbstractDevConsole { private int capacity = 25; private CamelEvent[] events; - private volatile int posEvents = -1; + private final AtomicInteger posEvents = new AtomicInteger(); private CamelEvent.RouteEvent[] routeEvents; - private volatile int posRoutes = -1; + private final AtomicInteger posRoutes = new AtomicInteger(); private CamelEvent.ExchangeEvent[] exchangeEvents; - private volatile int posExchanges = -1; + private final AtomicInteger posExchanges = new AtomicInteger(); private final ConsoleEventNotifier listener = new ConsoleEventNotifier(); public EventConsole() { @@ -61,7 +62,6 @@ public class EventConsole extends AbstractDevConsole { if (capacity > 1000 || capacity < 25) { throw new IllegalArgumentException("Capacity must be between 25 and 1000"); } - // capacity capped arrays, and we do not care about concurrency to avoid locking or slowdowns this.events = new CamelEvent[capacity]; this.routeEvents = new CamelEvent.RouteEvent[capacity]; this.exchangeEvents = new CamelEvent.ExchangeEvent[capacity]; @@ -80,18 +80,15 @@ public class EventConsole extends AbstractDevConsole { protected String doCallText(Map<String, Object> options) { StringBuilder sb = new StringBuilder(); - if (posEvents != -1) { - sb.append(appendTextEvents(events, "Camel", posEvents, capacity)); - sb.append("\n"); - } - if (posRoutes != -1) { - sb.append(appendTextEvents(routeEvents, "Route", posRoutes, capacity)); - sb.append("\n"); - } - if (posExchanges != -1) { - sb.append(appendTextEvents(exchangeEvents, "Exchange", posExchanges, capacity)); - sb.append("\n"); - } + int pos = posEvents.get(); + sb.append(appendTextEvents(events, "Camel", pos, capacity)); + sb.append("\n"); + pos = posRoutes.get(); + sb.append(appendTextEvents(routeEvents, "Route", pos, capacity)); + sb.append("\n"); + pos = posExchanges.get(); + sb.append(appendTextEvents(exchangeEvents, "Exchange", pos, capacity)); + sb.append("\n"); return sb.toString(); } @@ -99,23 +96,20 @@ public class EventConsole extends AbstractDevConsole { protected JsonObject doCallJson(Map<String, Object> options) { JsonObject root = new JsonObject(); - if (posEvents != -1) { - List<JsonObject> arr = appendJSonEvents(events, posEvents, capacity); - if (!arr.isEmpty()) { - root.put("events", arr); - } + int pos = posEvents.get(); + List<JsonObject> arr = appendJSonEvents(events, pos, capacity); + if (!arr.isEmpty()) { + root.put("events", arr); } - if (posRoutes != -1) { - List<JsonObject> arr = appendJSonEvents(routeEvents, posRoutes, capacity); - if (!arr.isEmpty()) { - root.put("routeEvents", arr); - } + pos = posRoutes.get(); + arr = appendJSonEvents(routeEvents, pos, capacity); + if (!arr.isEmpty()) { + root.put("routeEvents", arr); } - if (posExchanges != -1) { - List<JsonObject> arr = appendJSonEvents(exchangeEvents, posExchanges, capacity); - if (!arr.isEmpty()) { - root.put("exchangeEvents", arr); - } + pos = posExchanges.get(); + arr = appendJSonEvents(exchangeEvents, pos, capacity); + if (!arr.isEmpty()) { + root.put("exchangeEvents", arr); } return root; @@ -180,19 +174,17 @@ public class EventConsole extends AbstractDevConsole { @Override public void notify(CamelEvent event) throws Exception { - // for high concurrent load then exchange events may override - // that is okay as we do not want this console to cause slow-downs if (event instanceof CamelEvent.ExchangeEvent) { CamelEvent.ExchangeEvent ce = (CamelEvent.ExchangeEvent) event; - posExchanges = ++posExchanges % capacity; - exchangeEvents[posExchanges] = ce; + int pos = posExchanges.getAndUpdate(operand -> ++operand % capacity); + exchangeEvents[pos] = ce; } else if (event instanceof CamelEvent.RouteEvent) { CamelEvent.RouteEvent re = (CamelEvent.RouteEvent) event; - posRoutes = ++posRoutes % capacity; - routeEvents[posRoutes] = re; + int pos = posRoutes.getAndUpdate(operand -> ++operand % capacity); + routeEvents[pos] = re; } else { - posEvents = ++posEvents % capacity; - events[posEvents] = event; + int pos = posEvents.getAndUpdate(operand -> ++operand % capacity); + events[pos] = event; } }