Lambda: fix store typing for serialization#13707
Conversation
Test Results (amd64) - Integration, Bootstrap 5 files 5 suites 2h 0m 35s ⏱️ Results for commit 2ace1c8. ♻️ This comment has been updated with latest results. |
LocalStack Community integration with Pro 2 files ± 0 2 suites ±0 1h 29m 21s ⏱️ - 27m 57s Results for commit 2ace1c8. ± Comparison against base commit 4f689f3. This pull request removes 1436 tests.♻️ This comment has been updated with latest results. |
c735bfd to
75a148b
Compare
| working_directory: str | ||
| command: list[str] = dataclasses.field(default_factory=list) | ||
| entrypoint: list[str] = dataclasses.field(default_factory=list) | ||
| working_directory: str | None |
There was a problem hiding this comment.
I think we missed it. None values probably make sense here, as they connote a special meaning (it's not overridden to be empty, it's just not specified), in comparison to an empty list.
| license_info: str | ||
| compatible_runtimes: list[Runtime] | ||
| compatible_architectures: list[Architecture] | ||
| # we need to use Union types as inheritance is not supported by serialization framework |
There was a problem hiding this comment.
praise: Thanks for the clarifying comment. Good to know.
| # A LocalStack restart or persistence load should create a new instance id. | ||
| # Used for retaining invoke queues across version updates for $LATEST, but | ||
| # separate unrelated instances. | ||
| fn.instance_id = short_uid() |
There was a problem hiding this comment.
I am a little concerned that storing the ephemeral and internal instance_id in the model violates the assumption:
The instance id MUST be unique to the function and a given LocalStack instance
While this on_after_state_load approach fixes uniqueness for persistence loading, I wonder what happens when loading a CloudPod 🤔 . Does the instance_id get fixed there?
There might be a (small) chance to re-create the ugly race condition fixed in #10831 when deleting a function immediately followed by loading that same function from a CloudPod. wdyt @dfangl
There was a problem hiding this comment.
What alternatives do we have?
- Remove
instance_idfrom the models and store it in the service (discussed here) - Ensure loading a Pod/State containing a Lambda function resets the
instance_id - Offer some kind of
@ignoreannotation to skip serialization for volatile fields - 🤞
- ...
There was a problem hiding this comment.
Loading a Cloud Pod also triggers this hook 👍 so I don’t think this would be an issue? Except if we merge state, like restoring only functions in a specific account, but I don’t think this has been implemented yet, and the current logic would probably fail anyway?
if this is really an issue, I can try to write custom code to create a special class that would change value every time it’s restored, but that feels like abusing the system. Having the attribute somewhere else would be better
There was a problem hiding this comment.
I think it makes sense to leave it here, we do not support partial state loads anyway I think, and will always reload everything.
We have to keep in mind that the instance id now ends up in the state and gets overridden at load - my only fear is that it will bite us at some point if we forget about resetting it.
75a148b to
2ace1c8
Compare
dfangl
left a comment
There was a problem hiding this comment.
Thanks for tackling this! My only concern is the instance_id and what happens if we don't properly reset it after restoration, but for now this seems fine.
| working_directory: str | ||
| command: list[str] = dataclasses.field(default_factory=list) | ||
| entrypoint: list[str] = dataclasses.field(default_factory=list) | ||
| working_directory: str | None |
There was a problem hiding this comment.
I think we missed it. None values probably make sense here, as they connote a special meaning (it's not overridden to be empty, it's just not specified), in comparison to an empty list.
| # A LocalStack restart or persistence load should create a new instance id. | ||
| # Used for retaining invoke queues across version updates for $LATEST, but | ||
| # separate unrelated instances. | ||
| fn.instance_id = short_uid() |
There was a problem hiding this comment.
I think it makes sense to leave it here, we do not support partial state loads anyway I think, and will always reload everything.
We have to keep in mind that the instance id now ends up in the state and gets overridden at load - my only fear is that it will bite us at some point if we forget about resetting it.
Agreed, I think it would make sense for this field to be a "runtime variable" and having it live in some kind of global object outside the state, that would probably simplify things a bit? Thanks a lot for your reviews 🙏 |
Maybe, let's keep this in mind, but I would not change it in this PR honestly, we might not catch all implications, and this should make it in! |
Motivation
This PR improves Lambda typing to support more serialization frameworks.
Changes
VersionFunctionConfigurationto use the proper casing forCapacityProviderConfig: the TODO that was there was because the code was overriding the TypeDict definition as it was already declared in the scope 😬 also updated all usage of this attributeNoneUnion because it gets values straight from the provider requests, and those values can beNone(caught by the serialization framework with real values)code: serialization framework does not support parent class type hint / polymorphisminstance_idhack in theon_after_state_loadlogic as we're already iterating over allFunctionto avoid putting this on the serialization frameworkTests
Related
Done ✅
#13702 is also adding changes related toCapacityProviderConfigwhich still uses the wrong casing, rebase if it gets merged before 👍