rob-9 commented on code in PR #1094:
URL: https://github.com/apache/flink-agents/pull/1094#discussion_r3964382579


##########
runtime/src/main/java/org/apache/flink/agents/runtime/actionstate/ActionStateUtil.java:
##########
@@ -222,8 +222,11 @@ private static String generateUUIDForEvent(Event event) 
throws IOException {
     }
 
     private static String generateUUIDForAction(Action action) throws 
IOException {
+        // Action.hashCode() folds in JavaFunction's Class[] parameterTypes, 
and Class.hashCode()
+        // is the per-JVM identity hash — so the hash-derived UUID changes on 
every process
+        // restart and recovery lookups can never hit. Derive from the 
plan-unique action name,
+        // which is stable across restarts.
         return String.valueOf(
-                UUID.nameUUIDFromBytes(
-                        
String.valueOf(action.hashCode()).getBytes(StandardCharsets.UTF_8)));
+                
UUID.nameUUIDFromBytes(action.getName().getBytes(StandardCharsets.UTF_8)));

Review Comment:
   Question about compatibility: Python actions previously used a hash of 
stable strings, so their identifiers should've already been stable across 
restarts. 
   
   If a Python action saved a completed result before this change, I believe an 
upgraded job would end up looking for it under the new identifier and run the 
action again. 
   
   The name-based identifier makes sense, but I think we should clarify this 
upgrade case instead of saying no working deployment regresses, and explain how 
users should handle existing action state.



##########
runtime/src/test/java/org/apache/flink/agents/runtime/actionstate/ActionStateUtilTest.java:
##########
@@ -116,6 +118,43 @@ public void 
testGenerateKeyRejectsNonPositiveMaxParallelism() throws Exception {
                 () -> ActionStateUtil.generateKey(key, 1, action, inputEvent, 
-1));
     }
 
+    /**
+     * The action-UUID key segment must be derived from the plan-unique action 
NAME, never from
+     * {@code Action.hashCode()}: the hash folds in {@code Class.hashCode()} 
(a per-JVM identity
+     * hash), so a hash-derived segment silently changes across process 
restarts and recovery
+     * lookups can never hit. This pins the derivation so any future change to 
the key format is a
+     * conscious, reviewed break of cross-restart state compatibility.
+     */
+    @Test
+    public void testActionUUIDSegmentDerivesFromActionName() throws Exception {
+        Action action = new NoOpAction("test-action");
+        String generatedKey =
+                ActionStateUtil.generateKey(
+                        "test-key", 1, action, new InputEvent("test-input"), 
MAX_PARALLELISM);
+
+        String actionUUIDSegment = 
ActionStateUtil.parseKey(generatedKey).get(3);
+        assertEquals(
+                
UUID.nameUUIDFromBytes("test-action".getBytes(StandardCharsets.UTF_8)).toString(),
+                actionUUIDSegment);
+    }
+
+    /**
+     * Two separately constructed Action instances with the same name — which 
is what "the same
+     * action, after a JVM restart" looks like — must produce identical state 
keys, or recovery can
+     * never replay.
+     */
+    @Test
+    public void testSameActionNameYieldsSameKeyAcrossInstances() throws 
Exception {
+        InputEvent event = new InputEvent("test-input");
+        String first =
+                ActionStateUtil.generateKey(
+                        "test-key", 7, new NoOpAction("stable-name"), event, 
MAX_PARALLELISM);
+        String second =
+                ActionStateUtil.generateKey(
+                        "test-key", 7, new NoOpAction("stable-name"), event, 
MAX_PARALLELISM);
+        assertEquals(first, second);

Review Comment:
   Both actions here are created in the same JVM and share the same classes, so 
this test would also pass before the fix. 
   
   Could we add a test using separate JVMs or classloaders to exercise the 
original failure? The preceding test already catches reverting the identifier 
calculation; this would add coverage of the restart behavior described. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to