-
Notifications
You must be signed in to change notification settings - Fork 3
IWF-683 Add caching persistence data #104
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
Conversation
| @@ -0,0 +1,362 @@ | |||
| import inspect | |||
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.
Are these test files different? I did a quick check and seemed the same.
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.
They are slightly different.
This workflow is a copy of the one from the Java sdk, but the output from wait_for_workflow_completion is different here in python. I left this one for now even though the test is skipped to be able to recreate the issue.
The other workflow does largely the same things, but I changed it so the discrepancies wouldn't affect the tests themselves.
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.
Could you add a comment note in this test stating this? I think it might be beneficial in the future, in case we forget or someone else that doesn't have context looks at this
Otherwise, LGTM!
| class JavaDuplicateRpcMemoWorkflow(ObjectWorkflow): | ||
| def get_workflow_states(self) -> StateSchema: | ||
| return StateSchema.with_starting_state( | ||
| RpcMemoWorkflowState1(), RpcMemoWorkflowState2() | ||
| ) | ||
|
|
||
| def get_persistence_schema(self) -> PersistenceSchema: | ||
| return PersistenceSchema.create( | ||
| PersistenceField.data_attribute_def(TEST_DATA_OBJECT_KEY, str), | ||
| PersistenceField.search_attribute_def( | ||
| TEST_SEARCH_ATTRIBUTE_INT, SearchAttributeValueType.INT | ||
| ), | ||
| PersistenceField.search_attribute_def( | ||
| TEST_SEARCH_ATTRIBUTE_KEY, SearchAttributeValueType.KEYWORD | ||
| ), | ||
| ) | ||
|
|
||
| def get_communication_schema(self) -> CommunicationSchema: | ||
| return CommunicationSchema.create( | ||
| CommunicationMethod.internal_channel_def(INTERNAL_CHANNEL_NAME, None) | ||
| ) | ||
|
|
||
| def get_persistence_options(self) -> PersistenceOptions: | ||
| return PersistenceOptions(enable_caching=True) | ||
|
|
||
| @rpc() | ||
| def test_rpc_func1( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> int: | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
|
|
||
| persistence.set_data_attribute(TEST_DATA_OBJECT_KEY, None) | ||
| persistence.set_data_attribute(TEST_DATA_OBJECT_KEY, input) | ||
| persistence.set_search_attribute_keyword(TEST_SEARCH_ATTRIBUTE_KEY, input) | ||
| persistence.set_search_attribute_int64(TEST_SEARCH_ATTRIBUTE_INT, RPC_OUTPUT) | ||
| communication.publish_to_internal_channel(INTERNAL_CHANNEL_NAME, None) | ||
| communication.trigger_state_execution(RpcMemoWorkflowState2) | ||
| return RPC_OUTPUT | ||
|
|
||
| @rpc() | ||
| def test_rpc_func0( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> int: | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
|
|
||
| persistence.set_data_attribute(TEST_DATA_OBJECT_KEY, TEST_STR) | ||
| persistence.set_search_attribute_keyword(TEST_SEARCH_ATTRIBUTE_KEY, TEST_STR) | ||
| persistence.set_search_attribute_int64(TEST_SEARCH_ATTRIBUTE_INT, RPC_OUTPUT) | ||
| communication.publish_to_internal_channel(INTERNAL_CHANNEL_NAME, None) | ||
| communication.trigger_state_execution(RpcMemoWorkflowState2) | ||
| return RPC_OUTPUT | ||
|
|
||
| @rpc() | ||
| def test_rpc_proc1( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ): | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
|
|
||
| persistence.set_data_attribute(TEST_DATA_OBJECT_KEY, input) | ||
| persistence.set_search_attribute_keyword(TEST_SEARCH_ATTRIBUTE_KEY, input) | ||
| persistence.set_search_attribute_int64(TEST_SEARCH_ATTRIBUTE_INT, RPC_OUTPUT) | ||
| communication.publish_to_internal_channel(INTERNAL_CHANNEL_NAME, None) | ||
| communication.trigger_state_execution(RpcMemoWorkflowState2) | ||
|
|
||
| @rpc() | ||
| def test_rpc_proc0( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ): | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
|
|
||
| persistence.set_data_attribute(TEST_DATA_OBJECT_KEY, TEST_STR) | ||
| persistence.set_search_attribute_keyword(TEST_SEARCH_ATTRIBUTE_KEY, TEST_STR) | ||
| persistence.set_search_attribute_int64(TEST_SEARCH_ATTRIBUTE_INT, RPC_OUTPUT) | ||
| communication.publish_to_internal_channel(INTERNAL_CHANNEL_NAME, None) | ||
| communication.trigger_state_execution(RpcMemoWorkflowState2) | ||
|
|
||
| @rpc() | ||
| def test_rpc_func1_readonly( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> int: | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
| return RPC_OUTPUT | ||
|
|
||
| @rpc() | ||
| def test_rpc_set_data_attribute( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ): | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
| persistence.set_data_attribute(TEST_DATA_OBJECT_KEY, input) | ||
|
|
||
| @rpc() | ||
| def test_rpc_get_data_attribute( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> str: | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
| return persistence.get_data_attribute(TEST_DATA_OBJECT_KEY) | ||
|
|
||
| @rpc(bypass_caching_for_strong_consistency=True) | ||
| def test_rpc_get_data_attribute_strong_consistency( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> str: | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
| return persistence.get_data_attribute(TEST_DATA_OBJECT_KEY) | ||
|
|
||
| @rpc() | ||
| def test_rpc_set_keyword( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ): | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
| persistence.set_search_attribute_keyword(TEST_SEARCH_ATTRIBUTE_KEY, input) | ||
|
|
||
| @rpc(bypass_caching_for_strong_consistency=True) | ||
| def test_rpc_get_keyword_strong_consistency( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> Optional[str]: | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
| return persistence.get_search_attribute_keyword(TEST_SEARCH_ATTRIBUTE_KEY) | ||
|
|
||
| @rpc() | ||
| def test_rpc_get_keyword( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: str, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> Optional[str]: | ||
| if not ctx.workflow_id or not ctx.workflow_run_id: | ||
| raise RuntimeError("invalid context") | ||
| return persistence.get_search_attribute_keyword(TEST_SEARCH_ATTRIBUTE_KEY) | ||
|
|
||
|
|
||
| class RpcMemoWorkflowState1(WorkflowState[int]): | ||
| def wait_until( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: int, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> CommandRequest: | ||
| return CommandRequest.for_any_command_completed( | ||
| InternalChannelCommand.by_name(INTERNAL_CHANNEL_NAME) | ||
| ) | ||
|
|
||
| def execute( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: int, | ||
| command_results: CommandResults, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> StateDecision: | ||
| return StateDecision.single_next_state(RpcMemoWorkflowState2, 0) | ||
|
|
||
|
|
||
| class RpcMemoWorkflowState2(WorkflowState[int]): | ||
| _counter: int = 0 | ||
|
|
||
| def wait_until( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: int, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> CommandRequest: | ||
| return CommandRequest.empty() | ||
|
|
||
| def execute( | ||
| self, | ||
| ctx: WorkflowContext, | ||
| input: int, | ||
| command_results: CommandResults, | ||
| persistence: Persistence, | ||
| communication: Communication, | ||
| ) -> StateDecision: | ||
| self._counter += 1 | ||
| if self._counter == 2: | ||
| return StateDecision.graceful_complete_workflow(self._counter) | ||
| else: | ||
| return StateDecision.graceful_complete_workflow() | ||
|
|
||
| @classmethod | ||
| def reset_counter(cls) -> int: | ||
| old = cls._counter | ||
| cls._counter = 0 | ||
| return old |
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.
Nit: Can you move the workflow definition to the workflows directory?
| @classmethod | ||
| def setUpClass(cls): | ||
| wf = JavaDuplicateRpcMemoWorkflow() | ||
| registry.add_workflow(wf) |
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 would go to tests/__init__.py. Otherwise LGTM
5e0f139 to
e0386d3
Compare
No description provided.