-
Notifications
You must be signed in to change notification settings - Fork 91
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
Support dynamic resource parameters in Rib #960
Conversation
3ac3441
to
68e651d
Compare
Somewhere I messed up with stack interpreter
|
…o dynamic_resource_parameters
…o dynamic_resource_parameters
@@ -175,7 +175,7 @@ message CallExpr { | |||
|
|||
message InvocationName { | |||
oneof name { | |||
golem.rib.ParsedFunctionName parsed = 1; | |||
golem.rib.DynamicParsedFunctionName parsed = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this a breaking change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how? These are grpc types only for internal persistence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, discard my question. In terms of backward compatibility, well the function name is different now because has Exprs
in it, and it's a different structure. I need to test backward compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is internal persistence? If it is stored in any database, then this is a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to test/fix backward compatibility , which is what is remaining.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way to handle this would be to detect breakage and recompile from source. Since the IR is not exposed to the user.
Fixes #872 |
I will push 1 more change to avoid further "expects" that I found. |
for (arg, param_type) in args.iter_mut().zip(parameter_types) { | ||
check_function_arguments(¶m_type, arg)?; | ||
arg.add_infer_type_mut(param_type.clone().into()); | ||
arg.push_types_down()? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not required.
Fixes #872
There were several ways to solve this problem. Here is how I approached it, and had more subtle details to handle than I expected.
The introduction of
DynamicParsedFunctionName
(a concern that's only related to the Rib module) may contain Expr nodes within it. TheExpr::call
will now holdDynamicParsedFunctionName
.Some parts might sound a repetition but they are not unsafe repetition, because we need to successfully form the
ParsedFunctionName
with the details inDynamicParsedFunctionName
during Rib Instruction Execution.ParsedFunctionName
and associated functions are untouched, and therefore the change is NOT affecting any other modules such as the worker executor.ParsedFunctionName
implies that it's a fully formed function name, making it all type-safe.Rib IR
is now responsible for creating the function names based on parameters. As you can imagine, it internally forms theParsedFunctionName
which can be used to invoke the function in worker-service.The Instruction set has enough details on how to form the
ParsedFunctionName
safely. For examplerib::ir::FunctionReferenceType::IndexedResourceMethod(String, usize, String))
has details such as resource names, how many parameters to retrieve from the stack etc.The resource parameters in the stack are
TypeAnnotatedValue
, and we convert them towasm-wave syntax
string and then create theParsedFunctionName
. TThis may be slightly over-detailing, yet good to point out.
DynamicParsedFunctionName::parse
parsing is basically the mostly the same previous implementation ofParsedFunctionName::parse(str)
, and obviously the difference there is resource parameters areExpr
and notString
.ParseFunctionName::parse
simply delegates toDynamicParsedFunctionName::parse
, and modules such as worker-executor is using it and by that time, thestr
doesn't have any dynamic parameters (or unknown identifiers). This implies the result of DynamicParsedFunctionName::parsewill have theirs
Exprs containing fully formed values. This can be safely converted to
strusing
rib::to_string(expr)which is
wasm-wave` format.In other words,
ParsedFunctionName::parse
tests work as before. The only change in those text is in spaces. Example{ foo: "bar" }
is changed to{foo: "bar"}
.InvokeFunction
instruction is changed to first retrieve the the function name which is in stack created byCreateFunctionName
instruction, before popping up the resource/method parameters from the stack and then do the actual invocation.Another implication of all these change is, ensuring the type inference phase is aware of these
Exprs
that exist in theDynamicParsedFunctionName
.I had to also understand certain details to jump through some more hurdles and get things working, which took 1.5 more days than expected.
TODO
Serialize
andDeserialize
forRibByteCode
Test cases
Testing all the functions in the
cart
resource in a shopping cart componentNote:
I had a different approach before (an approach where the resource parameter could be static or dynamic, contained within
ParsedFunctionName
, which broke many things, affected many other modules, broke many tests to later realise that the above approach is the safest and robust approach.