weiqingy opened a new issue, #872:
URL: https://github.com/apache/flink-agents/issues/872

   ### Search before asking
   
   - [x] I searched in the 
[issues](https://github.com/apache/flink-agents/issues) and found nothing 
similar.
   
   ### Description
   
   Follow-up to #865 / #871. That fix makes a **top-level** `byte[]` 
`MemoryUpdate.value` survive the durable-execution serde round-trip. But the 
same root cause — `MemoryUpdate.value` is declared `Object` and 
`ActionStateSerde` uses a type-info-less Jackson `ObjectMapper` — still loses 
type for two nested/numeric cases that #871 deliberately left out of scope:
   
   1. **Nested `byte[]`**: a `byte[]` inside a `List` or `Map` memory value 
goes through Jackson's default serializers (not the field-scoped envelope added 
in #871), so it is written as a base64 `String` and, on crash/replay, recovered 
as a `String` instead of `byte[]`.
   
   2. **`Long` → `Integer` narrowing**: an untyped `Long` value within `int` 
range round-trips back as `Integer` (Jackson binds untyped JSON integers to the 
smallest fitting type). Out-of-`int`-range longs are unaffected. The same 
applies to such numbers nested inside a `List`/`Map`.
   
   Both are facets of the same `Object`-typed-serde type-loss family as #865 
(`byte[]` value) and #868/#869 (event-subclass nested attributes), but on a 
distinct field (`MemoryUpdate.value`, nested/numeric) with a distinct fix, so 
they're tracked separately here rather than folded into any of those.
   
   Severity is lower than #865 (nested/binary or int-range-`Long` memory values 
are less common than a top-level `byte[]`), but the corruption is silent, same 
as #865.
   
   ### How to reproduce
   
   Nested `byte[]` (in `ActionStateSerdeTest` style):
   
       Map<String, Object> value = new HashMap<>();
       value.put("blob", "hello".getBytes());
       ActionState state = new ActionState(null, null, null, null, null, false);
       state.addShortTermMemoryUpdate(new MemoryUpdate("stm.path", value));
   
       ActionState out = 
ActionStateSerde.deserialize(ActionStateSerde.serialize(state));
       Map<?, ?> recovered = (Map<?, ?>) 
out.getShortTermMemoryUpdates().get(0).getValue();
   
       // Expected: recovered.get("blob") is a byte[] equal to 
"hello".getBytes()
       // Actual:   recovered.get("blob") is a base64 String "aGVsbG8=", type 
lost
   
   `Long` → `Integer`:
   
       ActionState state = new ActionState(null, null, null, null, null, false);
       state.addShortTermMemoryUpdate(new MemoryUpdate("stm.path", 42L));
   
       ActionState out = 
ActionStateSerde.deserialize(ActionStateSerde.serialize(state));
       Object v = out.getShortTermMemoryUpdates().get(0).getValue();
   
       // Expected: v is a Long 42
       // Actual:   v is an Integer 42, type narrowed
   
   ### Version and environment
   
   0.1~0.3, and persists on `main` after #865/#871 (which only covers a 
top-level `byte[]` value).
   
   ### Are you willing to submit a PR?
   
   - [x] I'm willing to submit a PR!
   


-- 
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