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

Methods on objects returned from ctx.run are missing in 1.4.0 #454

Open
PfisterFactor opened this issue Oct 28, 2024 · 5 comments
Open

Methods on objects returned from ctx.run are missing in 1.4.0 #454

PfisterFactor opened this issue Oct 28, 2024 · 5 comments
Labels
documentation Improvements or additions to documentation

Comments

@PfisterFactor
Copy link

PfisterFactor commented Oct 28, 2024

Hey there,

I recently upgraded my restate-sdk from 1.3.1 to 1.4.0 and started getting a bunch of errors related to missing methods.

For example, I have a call like:

const object = await ctx.run(async () => await APIKeyModel.get(apiKey));
object["someProperty"] = 1;
object.save();

and it fails with object.save is undefined. I debugged the code and object is defined, but the methods are missing on it. I get errors like this on a bunch of areas in my codebase that return class objects.

This just started happening after the upgrade from 1.3.1 to 1.4.0. Not sure if context.run is JSON-ifying the object and removing methods on the return result. I had to downgrade back to 1.3.1 to fix it.

@mupperton
Copy link
Contributor

mupperton commented Oct 29, 2024

1.4.0 fixes a determinism issue, where previously you were receiving the exact value/reference returned by your inner run function, however the serialised-then-deserialised value which would be provided on replays could be different, therefore they now serialise the value first, then provide the user with the deserialised value, to ensure determinism across replays

Your ctx.run usage does not define a custom Serde, so it will be using the built-in JSON Serde, which does do a JSON.stringify and JSON.parse

You probably already had an issue on 1.3 with your code if you were to have any replays, it would fail on the same line because the deserialised value would also not have methods, you could test that now

More info: https://docs.restate.dev/develop/ts/serialization

@slinkydeveloper slinkydeveloper added the documentation Improvements or additions to documentation label Oct 29, 2024
@slinkydeveloper
Copy link
Contributor

@mupperton is indeed right, by default what you return from ctx.run gets serialized and deserialized using JSON, in order to enforce determinism. And indeed on replays object.save() would not work, even in <= 1.4.0

Perhaps this needs a sentence or two in the docs to clarify it.

@marcus-sa
Copy link

marcus-sa commented Oct 29, 2024

If you want to do this you can use https://deepkit.io/library/type for serialization and deserialization.
I've done exactly that in my integration here https://github.com/marcus-sa/deepkit-restate/blob/b25abbc90674aec2857856fbcbd77c14dcf2269e/src/restate-server.ts#L150

@PfisterFactor
Copy link
Author

Ah okay, I guess I'll have to do some refactors then to fix that issue. Thanks for the clarification!

@PfisterFactor
Copy link
Author

PfisterFactor commented Oct 29, 2024

Actually one more thing: would it be possible to update the return type of context.run to indicate that the object has been serialized/deserialized and is not the same as it was?

This way you could enforce correct handling of the result through the type system.

// type: () => Promise<{field: number, method: () => void}>
const apiCall = async () => {field: 123, method: () => console.log("hello world!")};

// type Promise<JSONified<{field: number, method: () => void}>>
// equivalent to: Promise<{field: number}>
const result = context.run(async () => await apiCall);

Something like this: microsoft/TypeScript#48697

@PfisterFactor PfisterFactor reopened this Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

4 participants