This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new 18af244bbf revert changes on workflowtracker, apache#5860 (#5897)
18af244bbf is described below
commit 18af244bbfae7dc4387c154197d5d0d7a3487f65
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Sat Oct 25 14:37:39 2025 +0200
revert changes on workflowtracker, apache#5860 (#5897)
* revert changes on workflowtracker, #5860
* fix broken chracters in chinese translation
---
.../org/apache/hop/core/gui/WorkflowTracker.java | 99 +-------
.../concurrency/WorkflowTrackerUniquenessTest.java | 262 ---------------------
.../apache/hop/core/gui/WorkflowTrackerTest.java | 19 +-
.../s3/s3common/messages/messages_zh_CN.properties | 2 +-
pom.xml | 2 +-
5 files changed, 7 insertions(+), 377 deletions(-)
diff --git a/engine/src/main/java/org/apache/hop/core/gui/WorkflowTracker.java
b/engine/src/main/java/org/apache/hop/core/gui/WorkflowTracker.java
index e1ee62de97..ceed48b485 100644
--- a/engine/src/main/java/org/apache/hop/core/gui/WorkflowTracker.java
+++ b/engine/src/main/java/org/apache/hop/core/gui/WorkflowTracker.java
@@ -18,12 +18,9 @@
package org.apache.hop.core.gui;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
-import java.util.Objects;
-import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import lombok.Getter;
import lombok.Setter;
@@ -43,12 +40,6 @@ public class WorkflowTracker<T extends WorkflowMeta> {
*/
private LinkedList<WorkflowTracker> workflowTrackers;
- /**
- * Set to track unique identifiers of workflow trackers to prevent
duplicates when actions run in
- * parallel
- */
- private Set<String> trackerIdentifiers;
-
/** If the workflowTrackers list is empty, then this is the result */
private ActionResult result;
@@ -83,7 +74,6 @@ public class WorkflowTracker<T extends WorkflowMeta> {
}
this.workflowTrackers = new LinkedList<>();
- this.trackerIdentifiers = new HashSet<>();
this.maxChildren = maxChildren;
this.lock = new ReentrantReadWriteLock();
}
@@ -114,21 +104,10 @@ public class WorkflowTracker<T extends WorkflowMeta> {
public void addWorkflowTracker(WorkflowTracker workflowTracker) {
lock.writeLock().lock();
try {
- String identifier = workflowTracker.getUniqueIdentifier();
-
- // Only add if this tracker is unique (not already present)
- if (identifier != null && !trackerIdentifiers.contains(identifier)) {
- workflowTrackers.add(workflowTracker);
- trackerIdentifiers.add(identifier);
-
- // Remove oldest entries if we exceed maxChildren
- while (workflowTrackers.size() > maxChildren) {
- WorkflowTracker removed = workflowTrackers.removeFirst();
- String removedId = removed.getUniqueIdentifier();
- if (removedId != null) {
- trackerIdentifiers.remove(removedId);
- }
- }
+ workflowTrackers.add(workflowTracker);
+ while (workflowTrackers.size() > maxChildren) {
+ // Use remove instead of subList
+ workflowTrackers.removeFirst();
}
} finally {
lock.writeLock().unlock();
@@ -175,16 +154,7 @@ public class WorkflowTracker<T extends WorkflowMeta> {
lock.writeLock().lock();
try {
this.workflowTrackers.clear();
- this.trackerIdentifiers.clear();
this.workflowTrackers.addAll(workflowTrackers);
-
- // Rebuild the identifier set
- for (WorkflowTracker tracker : workflowTrackers) {
- String identifier = tracker.getUniqueIdentifier();
- if (identifier != null) {
- this.trackerIdentifiers.add(identifier);
- }
- }
} finally {
lock.writeLock().unlock();
}
@@ -208,7 +178,6 @@ public class WorkflowTracker<T extends WorkflowMeta> {
lock.writeLock().lock();
try {
workflowTrackers.clear();
- trackerIdentifiers.clear();
result = null;
} finally {
lock.writeLock().unlock();
@@ -256,64 +225,4 @@ public class WorkflowTracker<T extends WorkflowMeta> {
lock.readLock().unlock();
}
}
-
- /**
- * Gets a unique identifier for this workflow tracker. Uses the log channel
ID to uniquely
- * identify each execution event. When actions run in parallel, the SAME
logChannelId means the
- * SAME execution event, which should be deduplicated. Different
logChannelIds means different
- * events.
- *
- * <p>Falls back to a combination of workflow name, action name, comment,
and timestamp if
- * logChannelId is not available.
- *
- * @return A unique identifier string, or null if insufficient information
- */
- public String getUniqueIdentifier() {
- if (result != null) {
- // Fallback: construct identifier from available fields
- StringBuilder identifier = new StringBuilder();
- if (workflowName != null) {
- identifier.append(workflowName).append("::");
- }
- if (workflowFilename != null) {
- identifier.append(workflowFilename);
- }
-
- return identifier.length() > 0 ? identifier.toString() : null;
- }
- return null;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- WorkflowTracker<?> that = (WorkflowTracker<?>) o;
-
- String thisId = this.getUniqueIdentifier();
- String thatId = that.getUniqueIdentifier();
-
- // If both have identifiers, compare them
- if (thisId != null && thatId != null) {
- return thisId.equals(thatId);
- }
-
- // Fallback to comparing workflow name and filename
- return Objects.equals(workflowName, that.workflowName)
- && Objects.equals(workflowFilename, that.workflowFilename)
- && Objects.equals(result, that.result);
- }
-
- @Override
- public int hashCode() {
- String identifier = getUniqueIdentifier();
- if (identifier != null) {
- return identifier.hashCode();
- }
- return Objects.hash(workflowName, workflowFilename, result);
- }
}
diff --git
a/engine/src/test/java/org/apache/hop/concurrency/WorkflowTrackerUniquenessTest.java
b/engine/src/test/java/org/apache/hop/concurrency/WorkflowTrackerUniquenessTest.java
deleted file mode 100644
index c37e9a04cf..0000000000
---
a/engine/src/test/java/org/apache/hop/concurrency/WorkflowTrackerUniquenessTest.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * 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.hop.concurrency;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import org.apache.hop.core.gui.WorkflowTracker;
-import org.apache.hop.workflow.ActionResult;
-import org.apache.hop.workflow.WorkflowMeta;
-import org.junit.Test;
-
-/**
- * Test to verify that WorkflowTracker enforces uniqueness per workflow
instance when multiple
- * threads attempt to add duplicate trackers concurrently (as happens when
actions run in parallel).
- * Each workflow (identified by name + filename) should only have one tracker.
- */
-public class WorkflowTrackerUniquenessTest {
-
- private static WorkflowMeta mockWorkflowMeta(String name) {
- WorkflowMeta meta = mock(WorkflowMeta.class);
- when(meta.getName()).thenReturn(name);
- return meta;
- }
-
- /**
- * Test that when multiple threads try to add WorkflowTrackers for the same
workflow, only one is
- * actually added (uniqueness is enforced at workflow level).
- */
- @Test
- public void testUniquenessWithSameWorkflow() throws Exception {
- WorkflowTracker tracker = new
WorkflowTracker(mockWorkflowMeta("parent-workflow"));
-
- final int NUM_THREADS = 10;
-
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- CountDownLatch startLatch = new CountDownLatch(1);
- CountDownLatch doneLatch = new CountDownLatch(NUM_THREADS);
-
- // All threads will try to add a tracker for the same child workflow
- for (int i = 0; i < NUM_THREADS; i++) {
- final int threadNum = i;
- executor.submit(
- () -> {
- try {
- startLatch.await(); // Wait for all threads to be ready
-
- ActionResult result =
- new ActionResult(
- null,
- "log-channel-" + threadNum, // Different log channels
- "Action started",
- null,
- "action-" + threadNum, // Different actions
- null);
-
- // All threads create trackers for the SAME workflow (same name)
- WorkflowTracker childTracker =
- new WorkflowTracker(mockWorkflowMeta("child-workflow"),
result);
- tracker.addWorkflowTracker(childTracker);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- } finally {
- doneLatch.countDown();
- }
- });
- }
-
- startLatch.countDown(); // Start all threads
- assertTrue("Threads did not complete in time", doneLatch.await(5,
TimeUnit.SECONDS));
- executor.shutdown();
-
- // Verify only ONE tracker was added for the child workflow (not 10)
- assertEquals("Expected only 1 unique tracker per workflow", 1,
tracker.nrWorkflowTrackers());
- }
-
- /**
- * Test that when multiple threads add WorkflowTrackers for DIFFERENT
workflows, all are added
- * (uniqueness is per workflow).
- */
- @Test
- public void testUniquenessWithDifferentWorkflows() throws Exception {
- WorkflowTracker tracker = new
WorkflowTracker(mockWorkflowMeta("parent-workflow"));
-
- final int NUM_THREADS = 10;
-
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- CountDownLatch startLatch = new CountDownLatch(1);
- CountDownLatch doneLatch = new CountDownLatch(NUM_THREADS);
-
- // Each thread adds a tracker for a DIFFERENT child workflow
- for (int i = 0; i < NUM_THREADS; i++) {
- final int threadNum = i;
- executor.submit(
- () -> {
- try {
- startLatch.await();
-
- ActionResult result =
- new ActionResult(
- null,
- "log-channel-" + threadNum,
- "Action started",
- null,
- "test-action-" + threadNum,
- null);
-
- // Each thread creates a tracker for a DIFFERENT workflow
- WorkflowTracker childTracker =
- new WorkflowTracker(mockWorkflowMeta("child-workflow-" +
threadNum), result);
- tracker.addWorkflowTracker(childTracker);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- } finally {
- doneLatch.countDown();
- }
- });
- }
-
- startLatch.countDown();
- assertTrue("Threads did not complete in time", doneLatch.await(5,
TimeUnit.SECONDS));
- executor.shutdown();
-
- // Verify all 10 unique workflow trackers were added (one per workflow)
- assertEquals(
- "Expected all 10 unique workflows to be tracked",
- NUM_THREADS,
- tracker.nrWorkflowTrackers());
-
- // Verify all identifiers are unique
- Set<String> identifiers = new HashSet<>();
- for (int i = 0; i < tracker.nrWorkflowTrackers(); i++) {
- WorkflowTracker child = tracker.getWorkflowTracker(i);
- String identifier = child.getUniqueIdentifier();
- assertTrue("Identifier should be unique: " + identifier,
identifiers.add(identifier));
- }
- }
-
- /**
- * Test that duplicate prevention works with workflow-level identifiers.
Multiple actions for the
- * same workflow should only create one tracker.
- */
- @Test
- public void testUniquenessPerWorkflow() throws Exception {
- WorkflowTracker tracker = new
WorkflowTracker(mockWorkflowMeta("parent-workflow"));
-
- final int NUM_THREADS = 5;
-
- ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
- CountDownLatch startLatch = new CountDownLatch(1);
- CountDownLatch doneLatch = new CountDownLatch(NUM_THREADS);
-
- // Create multiple trackers for the same workflow but different actions
- for (int i = 0; i < NUM_THREADS; i++) {
- final int threadNum = i;
- executor.submit(
- () -> {
- try {
- startLatch.await();
-
- ActionResult result = new ActionResult();
- result.setActionName("action-" + threadNum);
- result.setComment("Action started");
-
- // All threads try to add trackers for the SAME child workflow
- WorkflowTracker childTracker =
- new WorkflowTracker(mockWorkflowMeta("same-child-workflow"),
result);
- tracker.addWorkflowTracker(childTracker);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- } finally {
- doneLatch.countDown();
- }
- });
- }
-
- startLatch.countDown();
- assertTrue("Threads did not complete in time", doneLatch.await(10,
TimeUnit.SECONDS));
- executor.shutdown();
-
- // Only one tracker should be added for the workflow (not one per action)
- assertEquals("Expected only 1 tracker for the workflow", 1,
tracker.nrWorkflowTrackers());
- }
-
- /**
- * Test the getUniqueIdentifier method directly. It should use workflow name
and filename only.
- */
- @Test
- public void testGetUniqueIdentifier() {
- WorkflowMeta meta = mockWorkflowMeta("test-workflow");
-
- // Test with action result
- ActionResult result1 = new ActionResult(null, "channel-123", null, null,
"action-1", null);
-
- WorkflowTracker tracker1 = new WorkflowTracker(meta, result1);
- String identifier1 = tracker1.getUniqueIdentifier();
-
- // Should contain workflow name
- assertTrue("Identifier should contain workflow name",
identifier1.contains("test-workflow"));
-
- // Test that different actions in same workflow have same identifier
- ActionResult result2 = new ActionResult(null, "channel-456", "Started",
null, "action-2", null);
-
- WorkflowTracker tracker2 = new WorkflowTracker(meta, result2);
- String identifier2 = tracker2.getUniqueIdentifier();
-
- // Should be the same identifier (workflow-level, not action-level)
- assertEquals("Same workflow should have same identifier", identifier1,
identifier2);
- }
-
- /**
- * Test equals and hashCode methods. Trackers for the same workflow should
be equal, regardless of
- * action.
- */
- @Test
- public void testEqualsAndHashCode() {
- WorkflowMeta meta1 = mockWorkflowMeta("workflow-A");
- WorkflowMeta meta2 = mockWorkflowMeta("workflow-B");
-
- // Create two trackers for the same workflow but different actions
- ActionResult result1 = new ActionResult(null, "channel-1", null, null,
"action-1", null);
- ActionResult result2 = new ActionResult(null, "channel-2", null, null,
"action-2", null);
-
- WorkflowTracker tracker1 = new WorkflowTracker(meta1, result1);
- WorkflowTracker tracker2 = new WorkflowTracker(meta1, result2);
-
- // Should be equal because they're for the same workflow
- assertEquals("Trackers for same workflow should be equal", tracker1,
tracker2);
- assertEquals(
- "Hash codes should match for equal objects", tracker1.hashCode(),
tracker2.hashCode());
-
- // Create tracker for different workflow
- ActionResult result3 = new ActionResult(null, "channel-3", null, null,
"action-1", null);
- WorkflowTracker tracker3 = new WorkflowTracker(meta2, result3);
-
- // Should not be equal (different workflow)
- assertTrue("Trackers for different workflows should not be equal",
!tracker1.equals(tracker3));
- }
-}
diff --git
a/engine/src/test/java/org/apache/hop/core/gui/WorkflowTrackerTest.java
b/engine/src/test/java/org/apache/hop/core/gui/WorkflowTrackerTest.java
index 86808d04e7..9b0be55537 100644
--- a/engine/src/test/java/org/apache/hop/core/gui/WorkflowTrackerTest.java
+++ b/engine/src/test/java/org/apache/hop/core/gui/WorkflowTrackerTest.java
@@ -88,13 +88,8 @@ public class WorkflowTrackerTest {
@Test
public void findJobTracker_EntryNameFound() {
WorkflowTracker workflowTracker = createTracker();
- // Create trackers for different workflows (not just different actions)
WorkflowTracker[] children =
- new WorkflowTracker[] {
- createTrackerForWorkflow("workflow-0", "0"),
- createTrackerForWorkflow("workflow-1", "1"),
- createTrackerForWorkflow("workflow-2", "2")
- };
+ new WorkflowTracker[] {createTracker("0"), createTracker("1"),
createTracker("2")};
for (WorkflowTracker child : children) {
workflowTracker.addWorkflowTracker(child);
}
@@ -119,18 +114,6 @@ public class WorkflowTrackerTest {
return workflowTracker;
}
- private static WorkflowTracker createTrackerForWorkflow(String workflowName,
String actionName) {
- WorkflowMeta workflowMeta = mock(WorkflowMeta.class);
- when(workflowMeta.getName()).thenReturn(workflowName);
- WorkflowTracker workflowTracker = new WorkflowTracker(workflowMeta);
- if (actionName != null) {
- ActionResult result = mock(ActionResult.class);
- when(result.getActionName()).thenReturn(actionName);
- workflowTracker.setActionResult(result);
- }
- return workflowTracker;
- }
-
private static ActionMeta createActionMeta(String actionName) {
IAction action = mock(IAction.class);
when(action.getName()).thenReturn(actionName);
diff --git
a/plugins/tech/aws/src/main/resources/org/apache/hop/vfs/s3/s3common/messages/messages_zh_CN.properties
b/plugins/tech/aws/src/main/resources/org/apache/hop/vfs/s3/s3common/messages/messages_zh_CN.properties
index 3be9a23a57..aa4d1d511e 100644
---
a/plugins/tech/aws/src/main/resources/org/apache/hop/vfs/s3/s3common/messages/messages_zh_CN.properties
+++
b/plugins/tech/aws/src/main/resources/org/apache/hop/vfs/s3/s3common/messages/messages_zh_CN.properties
@@ -22,4 +22,4 @@ ERROR.S3MultiPart.ExceptionCaught=S3
\u5206\u6BB5\u4E0A\u4F20\u65F6\u610F\u5916\
ERROR.S3MultiPart.UploadOutOfMemory=S3
\u5206\u6BB5\u4E0A\u4F20\u65F6\u5F15\u53D1\u5185\u5B58\u4E0D\u8DB3\u7684\u9519\u8BEF,
\u8BF7\u964D\u4F4E\u5206\u6BB5\u6570, \u5F53\u524D partSize\: {0}
INFO.S3MultiPart.Complete=S3 \u5206\u6BB5\u4E0A\u4F20\u5B8C\u6210
INFO.S3MultiPart.Start=\u5F00\u59CB S3 \u5206\u6BB5\u4E0A\u4F20...
-INFO.S3MultiPart.Upload=S3\u5206\u6BB5\u4E0A\u4F20 [partnumber\uFF1A{0},
file\u001DOffset\uFF1A{1}, partsize\uFF1A{2}]
+INFO.S3MultiPart.Upload=S3\u5206\u6BB5\u4E0A\u4F20 [partnumber: {0},
fileOffset: {1}, partsize: {2}]
diff --git a/pom.xml b/pom.xml
index 501537ba7d..33bac1bd9c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -611,7 +611,7 @@
</activation>
<properties>
<env>mac</env>
-
<swt.artifactId>org.eclipse.swt.cocoa.macosx.x86_64</swt.artifactId>
+
<swt.artifactId>org.eclipse.swt.cocoa.macosx.aarch64</swt.artifactId>
</properties>
<dependencyManagement>
<dependencies>