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

rpuch pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new c02f925e799 IGNITE-28235 Only log cause of broken watch notification 
chain once (#7787)
c02f925e799 is described below

commit c02f925e7991746af8479492adf71f8459ee0ff2
Author: Roman Puchkovskiy <[email protected]>
AuthorDate: Mon Mar 16 14:32:16 2026 +0400

    IGNITE-28235 Only log cause of broken watch notification chain once (#7787)
---
 .../testframework/log4j2/LogInspector.java         |  8 +-
 .../metastorage/impl/ItBrokenWatchLoggingTest.java | 91 ++++++++++++++++++++++
 .../metastorage/server/UpdateEntriesEvent.java     | 12 +--
 3 files changed, 99 insertions(+), 12 deletions(-)

diff --git 
a/modules/core/src/testFixtures/java/org/apache/ignite/internal/testframework/log4j2/LogInspector.java
 
b/modules/core/src/testFixtures/java/org/apache/ignite/internal/testframework/log4j2/LogInspector.java
index ae31fcf69fb..5359a17b7ac 100755
--- 
a/modules/core/src/testFixtures/java/org/apache/ignite/internal/testframework/log4j2/LogInspector.java
+++ 
b/modules/core/src/testFixtures/java/org/apache/ignite/internal/testframework/log4j2/LogInspector.java
@@ -87,6 +87,12 @@ import org.apache.logging.log4j.core.config.Property;
  * </p>
  */
 public class LogInspector {
+    // TODO: https://issues.apache.org/jira/browse/IGNITE-28236 - instead of a 
magic constant, pass null or use specific static factories.
+    /**
+     * Magic 'logger name' that makes the inspector catch events from all 
loggers when passed as a logger name.
+     */
+    public static final String ALL_LOGGERS = "all-loggers";
+
     /** Logger name. */
     private final String loggerName;
 
@@ -391,7 +397,7 @@ public class LogInspector {
 
         @Override
         public void append(LogEvent event) {
-            if (!loggerName.equals(event.getLoggerName())) {
+            if (!ALL_LOGGERS.equals(loggerName) && 
!loggerName.equals(event.getLoggerName())) {
                 return;
             }
 
diff --git 
a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItBrokenWatchLoggingTest.java
 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItBrokenWatchLoggingTest.java
new file mode 100644
index 00000000000..005dc525730
--- /dev/null
+++ 
b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItBrokenWatchLoggingTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.metastorage.impl;
+
+import static java.util.UUID.randomUUID;
+import static java.util.concurrent.CompletableFuture.failedFuture;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.internal.TestWrappers.unwrapIgniteImpl;
+import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.waitForCondition;
+import static org.apache.ignite.internal.util.ExceptionUtils.hasCause;
+import static org.awaitility.Awaitility.await;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.internal.ClusterPerTestIntegrationTest;
+import org.apache.ignite.internal.ConfigOverride;
+import org.apache.ignite.internal.lang.ByteArray;
+import org.apache.ignite.internal.metastorage.MetaStorageManager;
+import 
org.apache.ignite.internal.testframework.failure.FailureManagerExtension;
+import 
org.apache.ignite.internal.testframework.failure.MuteFailureManagerLogging;
+import org.apache.ignite.internal.testframework.log4j2.LogInspector;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(FailureManagerExtension.class)
+@MuteFailureManagerLogging
+@ConfigOverride(name = "ignite.failureHandler.handler.type", value = "noop")
+class ItBrokenWatchLoggingTest extends ClusterPerTestIntegrationTest {
+    @Override
+    protected int initialNodes() {
+        return 1;
+    }
+
+    @Test
+    void brokenWatchChainLogsOriginalExceptionJustOnce() throws Exception {
+        MetaStorageManager metaStorageManager = 
unwrapIgniteImpl(cluster.node(0)).metaStorageManager();
+
+        registerWatchBreakingNotifications(metaStorageManager);
+
+        AtomicInteger logCount = new AtomicInteger();
+
+        LogInspector logInspector = new LogInspector(
+                LogInspector.ALL_LOGGERS,
+                evt -> hasCause(evt.getThrown(), BreakingException.class),
+                logCount::incrementAndGet
+        );
+        logInspector.start();
+
+        try {
+            await("Must observe at least one logging event")
+                    .until(logCount::get, greaterThan(0));
+
+            //noinspection deprecation
+            assertFalse(
+                    waitForCondition(() -> logCount.get() > 1, 
SECONDS.toMillis(2)),
+                    () -> "Must not observe more than one logging event, but 
observed " + logCount.get()
+            );
+        } finally {
+            logInspector.stop();
+        }
+    }
+
+    private static void registerWatchBreakingNotifications(MetaStorageManager 
metaStorageManager) {
+        BreakingException exception = new BreakingException("Oops " + 
randomUUID());
+        metaStorageManager.registerPrefixWatch(new ByteArray(""), event -> 
failedFuture(exception));
+    }
+
+    private static class BreakingException extends RuntimeException {
+        private static final long serialVersionUID = -8004315686224616385L;
+
+        private BreakingException(String message) {
+            super(message);
+        }
+    }
+}
diff --git 
a/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/server/UpdateEntriesEvent.java
 
b/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/server/UpdateEntriesEvent.java
index 32ad8640299..5418979132b 100644
--- 
a/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/server/UpdateEntriesEvent.java
+++ 
b/modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/server/UpdateEntriesEvent.java
@@ -19,16 +19,12 @@ package org.apache.ignite.internal.metastorage.server;
 
 import java.util.List;
 import org.apache.ignite.internal.hlc.HybridTimestamp;
-import org.apache.ignite.internal.logger.IgniteLogger;
-import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.metastorage.Entry;
 import org.apache.ignite.internal.tostring.IgniteToStringInclude;
 import org.apache.ignite.internal.tostring.S;
 
 /** Notifier of {@link WatchProcessor} about updating metastorage {@link Entry 
entries}. */
 public class UpdateEntriesEvent implements NotifyWatchProcessorEvent {
-    private static final IgniteLogger LOG = 
Loggers.forClass(UpdateEntriesEvent.class);
-
     @IgniteToStringInclude
     private final List<Entry> updatedEntries;
 
@@ -50,13 +46,7 @@ public class UpdateEntriesEvent implements 
NotifyWatchProcessorEvent {
 
     @Override
     public void notify(WatchProcessor watchProcessor) {
-        watchProcessor.notifyWatches(updatedEntries.get(0).revision(), 
updatedEntries, timestamp)
-                .whenComplete((res, err) -> {
-                    if (err != null) {
-                        // TODO: 
https://issues.apache.org/jira/browse/IGNITE-26731
-                        LOG.error("Notify watches failed.", err);
-                    }
-                });
+        watchProcessor.notifyWatches(updatedEntries.get(0).revision(), 
updatedEntries, timestamp);
     }
 
     @Override

Reply via email to