Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix typed arrays serialization deserialization #2927

Conversation

bourdaisj
Copy link
Contributor

Context

The behavior of JSON.stringify for typed arrays is to serialize them as objects with numeric keys. This cause crashes when re-building the object since it would try to fit an object where a typed array is required. This changes makes it so getState replaces typed arrays with plain javascript arrays.

Typical example is vtkImageData direction property, which is by default Float64Array
minimal reproduction:

import vtk from '@kitware/vtk.js/vtk';
import vtkImageData from '../../Sources/Common/DataModel/ImageData';

const imdt = vtkImageData.newInstance();
const jsonRepr = JSON.stringify(imdt);
const jsonDeserialize = JSON.parse(jsonRepr);

const vtkObj = vtk(jsonDeserialize); // this should crash

see also Kitware/glance#480

Results

makes serialization/deserialization possible and successful

Changes

  • Documentation and TypeScript definitions were updated to match those changes

This change makes it so we serialize typed arrays as arrays.

PR and Code Checklist

  • semantic-release commit messages
  • Run npm run reformat to have correctly formatted code

Testing

  • This change adds or fixes unit tests
  • Tested environment:
    • vtk.js: master
    • OS: linux
    • Browser: chrome, firefox latest

@bourdaisj bourdaisj self-assigned this Sep 29, 2023
@bourdaisj bourdaisj requested a review from floryst September 29, 2023 09:32
@bourdaisj
Copy link
Contributor Author

fyi @finetjul @bruyeret

Copy link
Contributor

@bruyeret bruyeret left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Copy link
Member

@finetjul finetjul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can think of 2 better (not orthogonal) alternatives:

  • vtkImageData.indexToWorld and worldToIndex must not be typed array but regular arrays, which are 64 bits anyway.
  • vtkImageData.indexToWorld and worldToIndex shall not be serialized but must be flagged as protected by adding _ prefix and recomputed at deserialization.

@bourdaisj
Copy link
Contributor Author

to me those are not alternatives to the fix I'm proposing which is necessary but definitely you have a good point.
probably gonna include those in the scope of this PR

@finetjul
Copy link
Member

to me those are not alternatives to the fix I'm proposing which is necessary but definitely you have a good point.
probably gonna include those in the scope of this PR

I agree, your fix is also necessary.
I have that bad habit to not willing to fix a crash if it can help detect bad design in the first place.

@bourdaisj
Copy link
Contributor Author

we actually uses Float64Array a lot for gl-matrix math related stuff. so I wouldn't call it 'bad design' in this case.
if we change that in vtkImageData we would need to update everything to use plain old JS arrays to maintain consistency, and I don't think that's worth it/ Let's keep the simple fix for this PR imo.

Sources/macros.js Outdated Show resolved Hide resolved
@floryst
Copy link
Collaborator

floryst commented Oct 2, 2023

The image direction matrices are a consequence of using gl-matrix for construction and allocation, since it defaults to Float32Arrays. I partially agree with @finetjul that the index/world transform matrices should be hidden from serialization, but having them is nice for downstream code to not have to always recompute the transforms upon deserialization (e.g. sending over the network).

the behavior of JSON.stringify for typed arrays is to serialize them as objects with numeric keys.
This cause crashes when re-building the object since it would try to fit an object where a typed
array is required. This changes makes it so getState replaces typed arrays with plain javascript
arrays.
@bourdaisj bourdaisj force-pushed the fix-typed-arrays-serialization-deserialization branch from fb62f4c to 0ede1a2 Compare October 3, 2023 07:14
@bourdaisj
Copy link
Contributor Author

Thanks for review and feedback guys!
I don't know what's better. I can open an issue to keep track of this discussion. Tbh I just want to get Kitware/glance#480 fixed in this PR

@finetjul finetjul added this pull request to the merge queue Oct 3, 2023
@finetjul
Copy link
Member

finetjul commented Oct 3, 2023

Let's leave it as is.

Merged via the queue into Kitware:master with commit 96fcd1f Oct 3, 2023
4 checks passed
@github-actions
Copy link

github-actions bot commented Oct 3, 2023

🎉 This PR is included in version 28.12.4 🎉

The release is available on:

Your semantic-release bot 📦🚀

@github-actions github-actions bot added the released Automated label label Oct 3, 2023
@bourdaisj bourdaisj deleted the fix-typed-arrays-serialization-deserialization branch January 24, 2024 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
released Automated label
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants