This is an automated email from the ASF dual-hosted git repository.
ruanwenjun pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new e973efad92 [Fix-18292][Registry] Carry deleted node value in JDBC
registry REMOVE event (#18296)
e973efad92 is described below
commit e973efad927d38d1a3b7f10a65bb97d39a3474e1
Author: Wenjun Ruan <[email protected]>
AuthorDate: Tue May 26 18:50:09 2026 +0800
[Fix-18292][Registry] Carry deleted node value in JDBC registry REMOVE
event (#18296)
The JDBC registry built REMOVE events without eventData, so downstream
listeners (AbstractClusterSubscribeListener / AbstractHAServer) parsed a
null heartbeat, logged "Unknown cluster change event" and dropped the
event, leaving stale master/slot state in memory after ephemeral nodes
were purged.
Thread the deleted node value through onJdbcRegistryDataDeleted so the
REMOVE event carries it as eventData, matching the ZooKeeper and Etcd
registries.
---
.../JdbcRegistryDataChangeListenerAdapter.java | 3 +-
.../server/JdbcRegistryDataChangeListener.java | 2 +-
.../registry/jdbc/server/JdbcRegistryServer.java | 3 +-
.../JdbcRegistryDataChangeListenerAdapterTest.java | 72 ++++++++++++++++++++++
4 files changed, 77 insertions(+), 3 deletions(-)
diff --git
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistryDataChangeListenerAdapter.java
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistryDataChangeListenerAdapter.java
index ccfb95f963..a39426f9bb 100644
---
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistryDataChangeListenerAdapter.java
+++
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistryDataChangeListenerAdapter.java
@@ -46,13 +46,14 @@ public class JdbcRegistryDataChangeListenerAdapter
implements JdbcRegistryDataCh
}
@Override
- public void onJdbcRegistryDataDeleted(String eventPath) {
+ public void onJdbcRegistryDataDeleted(String eventPath, String value) {
if (!isPathMatch(watchedPath, eventPath,
listener.getSubscribeScope())) {
return;
}
final Event event = Event.builder()
.watchedPath(watchedPath)
.eventPath(eventPath)
+ .eventData(value)
.type(Event.Type.REMOVE)
.build();
listener.notify(event);
diff --git
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryDataChangeListener.java
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryDataChangeListener.java
index cea1df2149..d02e4259ef 100644
---
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryDataChangeListener.java
+++
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryDataChangeListener.java
@@ -21,7 +21,7 @@ public interface JdbcRegistryDataChangeListener {
void onJdbcRegistryDataChanged(String key, String value);
- void onJdbcRegistryDataDeleted(String key);
+ void onJdbcRegistryDataDeleted(String key, String value);
void onJdbcRegistryDataAdded(String key, String value);
diff --git
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java
index 3e8b11c813..61a934bd14 100644
---
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java
+++
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/java/org/apache/dolphinscheduler/plugin/registry/jdbc/server/JdbcRegistryServer.java
@@ -196,7 +196,8 @@ public class JdbcRegistryServer implements
IJdbcRegistryServer {
@Override
public void onRegistryRowDeleted(JdbcRegistryDataDTO data)
{
-
jdbcRegistryDataChangeListener.onJdbcRegistryDataDeleted(data.getDataKey());
+
jdbcRegistryDataChangeListener.onJdbcRegistryDataDeleted(data.getDataKey(),
+ data.getDataValue());
}
});
}
diff --git
a/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/test/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistryDataChangeListenerAdapterTest.java
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/test/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistryDataChangeListenerAdapterTest.java
new file mode 100644
index 0000000000..efe16ac7d8
--- /dev/null
+++
b/dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/test/java/org/apache/dolphinscheduler/plugin/registry/jdbc/JdbcRegistryDataChangeListenerAdapterTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.dolphinscheduler.plugin.registry.jdbc;
+
+import org.apache.dolphinscheduler.registry.api.Event;
+import org.apache.dolphinscheduler.registry.api.SubscribeListener;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.Test;
+
+import com.google.common.truth.Truth;
+
+class JdbcRegistryDataChangeListenerAdapterTest {
+
+ private static final String WATCHED_PATH = "/nodes/master";
+
+ /**
+ * The REMOVE event must carry the deleted node value as eventData,
otherwise downstream listeners
+ * (e.g. AbstractClusterSubscribeListener / AbstractHAServer) cannot parse
the removed server and will
+ * silently drop the event, leaving stale registry data in memory.
+ */
+ @Test
+ void onJdbcRegistryDataDeleted_shouldInjectDeletedValueAsEventData() {
+ final String eventPath = "/nodes/master/127.0.0.1:5678";
+ final String deletedValue = "{\"address\":\"127.0.0.1:5678\"}";
+ final AtomicReference<Event> notified = new AtomicReference<>();
+
+ final JdbcRegistryDataChangeListenerAdapter adapter = new
JdbcRegistryDataChangeListenerAdapter(
+ WATCHED_PATH, capturingListener(notified,
SubscribeListener.SubscribeScope.CHILDREN_ONLY));
+
+ adapter.onJdbcRegistryDataDeleted(eventPath, deletedValue);
+
+ final Event event = notified.get();
+ Truth.assertThat(event).isNotNull();
+ Truth.assertThat(event.getType()).isEqualTo(Event.Type.REMOVE);
+ Truth.assertThat(event.getWatchedPath()).isEqualTo(WATCHED_PATH);
+ Truth.assertThat(event.getEventPath()).isEqualTo(eventPath);
+ Truth.assertThat(event.getEventData()).isEqualTo(deletedValue);
+ }
+
+ private SubscribeListener capturingListener(final AtomicReference<Event>
holder,
+ final
SubscribeListener.SubscribeScope scope) {
+ return new SubscribeListener() {
+
+ @Override
+ public void notify(final Event event) {
+ holder.set(event);
+ }
+
+ @Override
+ public SubscribeScope getSubscribeScope() {
+ return scope;
+ }
+ };
+ }
+}