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(api): filter get_run_commands #16001

Conversation

TamarZanzouri
Copy link
Contributor

@TamarZanzouri TamarZanzouri commented Aug 14, 2024

Overview

closes EXEC-654.
get filtered command list

Test Plan and Hands on Testing

  • upload a protocol that will enter ER.
  • add some fixit commands.
  • make sure you dont see the fixit commands in the run log.

Changelog

  • added an arg allCommands to get_run_commands.
  • add logic to CommandState and CommandHistory to filter based on the protocol intent.

Review requests

changes make sense? how ugly is this?

Risk assessment

Medium. need to make sure nothing that uses run commands changed the default behavior.

@@ -127,6 +130,28 @@ def get_running_command(self) -> Optional[CommandEntry]:
else:
return self._commands_by_id[self._running_command_id]

def get_filtered_command_ids(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

should we add protocol intent filter? probably?

total_length = self._state.command_history.length()
command_ids = self._state.command_history.get_filtered_command_ids(
command_intents=[
CommandIntent.PROTOCOL,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

kind of hate this. should we just change this to a list of intents in robot server?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm totally neutral about it, but I think this also depends on the performance questions in CommandHistory (see my other comment). So let's come back to this.

@TamarZanzouri TamarZanzouri changed the title Exec 654 unsafe drop in place appears in run preview fix(api): filter get_run_commands Aug 14, 2024
@TamarZanzouri TamarZanzouri marked this pull request as ready for review August 14, 2024 20:03
@TamarZanzouri TamarZanzouri requested a review from a team as a code owner August 14, 2024 20:03
@TamarZanzouri TamarZanzouri requested review from mjhuff and SyntaxColoring and removed request for a team August 14, 2024 20:03
@@ -127,6 +130,28 @@ def get_running_command(self) -> Optional[CommandEntry]:
else:
return self._commands_by_id[self._running_command_id]

def get_filtered_command_ids(
self,
command_intents: list[CommandIntent] = [
Copy link
Contributor Author

Choose a reason for hiding this comment

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

should we change this to bool and add the logic within?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it depends on how the performance questions (in my other comment) get solved. You may find that it's too much work to get it to accept arbitrary CommandIntents, and we can only filter FIXIT for now.

So I guess let's focus on that question and then come back to this.

Copy link
Contributor

@SyntaxColoring SyntaxColoring left a comment

Choose a reason for hiding this comment

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

This all makes sense to me from a correctness standpoint. I am concerned about performance, though, so let's test to make sure we're good there, before merging this.

@@ -127,6 +130,28 @@ def get_running_command(self) -> Optional[CommandEntry]:
else:
return self._commands_by_id[self._running_command_id]

def get_filtered_command_ids(
self,
command_intents: list[CommandIntent] = [
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it depends on how the performance questions (in my other comment) get solved. You may find that it's too much work to get it to accept arbitrary CommandIntents, and we can only filter FIXIT for now.

So I guess let's focus on that question and then come back to this.

Comment on lines +140 to +153
filtered_command = self._commands_by_id
if CommandIntent.FIXIT not in command_intents:
filtered_command = {
key: val
for key, val in self._commands_by_id.items()
if val.command.intent != CommandIntent.FIXIT
}
if CommandIntent.SETUP not in command_intents:
filtered_command = {
key: val
for key, val in filtered_command.items()
if val.command.intent != CommandIntent.SETUP
}
return list(filtered_command.keys())
Copy link
Contributor

@SyntaxColoring SyntaxColoring Aug 14, 2024

Choose a reason for hiding this comment

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

I'm concerned about the performance of this implementation.

Formerly, if an HTTP client asked to retrieve n commands, we could do it in average O(n) time. Now, if a client asks to retrieve n filtered commands, it will take O(m) time, where m is the number of total commands in the run. This could be quite bad if the run is long and the client is polling us for the run log.

I think before merging, we need to confirm with testing that response times will stay acceptable even with, say, a 10,000-command protocol. (I'm getting the number 10,000 from here—it's pessimistic but realistic.)

A more performant way to implement this will probably involve some kind of speedup index, like we do for _queued_setup_command_ids, etc. It may also involve combining the filtering and slicing steps.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree. I told Jamey that I am concerned from the performance as well. The problem is that we have a fixit_queued_commad_ids but once it's executed it's not in the queue anymore, it's just in the commands queue. This was my first implementation but found bugs related to that. I will explore other options.

total_length = self._state.command_history.length()
command_ids = self._state.command_history.get_filtered_command_ids(
command_intents=[
CommandIntent.PROTOCOL,
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm totally neutral about it, but I think this also depends on the performance questions in CommandHistory (see my other comment). So let's come back to this.

@@ -1006,6 +1006,51 @@ def test_get_slice_default_cursor_running() -> None:
)


def test_get_slice_without_fixit() -> None:
Copy link
Contributor

@SyntaxColoring SyntaxColoring Aug 14, 2024

Choose a reason for hiding this comment

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

Can we add this in test_command_state instead, if you have time? For the reasons described at the top of this file.

This is a lower-priority request because the CommandView.get_slice() tests have a lot of confusing overlap with the ones for CommandHistory and I would not mind if we just ignored it for now. :^)

@TamarZanzouri
Copy link
Contributor Author

Decided to go with a FE change for now. I backend change will involve DB changes. Decided to punt on this for now.
see https://opentrons.slack.com/archives/C06M9F26YGH/p1723753502607629 for context.

TamarZanzouri added a commit that referenced this pull request Sep 13, 2024
…ist (#16075)

# Overview

reference #16001 for previous
pr comments.
closes [EXEC-654](https://opentrons.atlassian.net/browse/EXEC-654).
get filtered command list for historical runs and for current runs.

## Test Plan and Hands on Testing

- upload a protocol that will enter ER.
- add some fixit commands.
- make sure you dont see the fixit commands in the run log. 
- when the run is completed and un-current make sure you still dont see
fixit commands.

## Changelog

- added an arg `includeFixitCommands` to `get_run_commands` route.
- add logic to `CommandState` and `CommandHistory` to filter based on
the protocol intent.
- added column `command_intent` to `run_command_table` and migration
scripts.
- fixed but with copying over enum columns in the DB. 
- added filtering in the sql query for command intent. 

## Review requests

changes make sense? how ugly is this? 

## Risk assessment

Medium. need to make sure run commands did not changed the default
behavior.

[EXEC-654]:
https://opentrons.atlassian.net/browse/EXEC-654?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

---------

Co-authored-by: Seth Foster <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants