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

Improves import times by delaying imports when needed #13281

Merged

Conversation

bsignoret
Copy link
Contributor

In some places, imports can be moved for faster loading times.

Example

On my computer, here's the result (it's not a precise measurement):
python -X importtime -c "from prefect import Runner"

before:

import time: 230957 | 1496253 | prefect

after:

import time: 215386 | 828572 | prefect

Checklist

  • This pull request references any related issue by including "closes <link to issue>"
    • If no issue exists and your change is not a small fix, please create an issue first.
  • If this pull request adds new functionality, it includes unit tests that cover the changes
  • This pull request includes a label categorizing the change e.g. maintenance, fix, feature, enhancement, docs.

For documentation changes:

  • This pull request includes redirect settings in netlify.toml for files that are removed or renamed.

For new functions or classes in the Python SDK:

  • This pull request includes helpful docstrings.
  • If a new Python file was added, this pull request contains a stub page in the Python SDK docs and an entry in mkdocs.yml navigation.

@bsignoret bsignoret requested a review from a team as a code owner May 8, 2024 10:31
Copy link

netlify bot commented May 8, 2024

👷 Deploy request for prefect-docs-preview pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 88deac8

Comment on lines +5 to +6
if TYPE_CHECKING:
from prefect.client.schemas.schedules import SCHEDULE_TYPES
Copy link
Contributor

Choose a reason for hiding this comment

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

@bunchesofdonald Are you able to comment on why this one is currently prefect.server? It seemed to be backwards compatibility for build_from_flow based on the PR I saw, but wanted to double check on it

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, essentially. Since we're doing an isinstance check we need to check against the server's version for that to work out, the client's version isn't the same instance. Having this behind a TYPE_CHECKING flag should be fine.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, cool, what I'm hearing is that we should then probably do:

if TYPE_CHECKING:
    from prefect.server.schemas.schedules import SCHEDULE_TYPES

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hello!
Currently (Before this PR), we have:

from prefect.client.schemas.schedules import SCHEDULE_TYPES

SERVER_SCHEDULE_TYPES (prefect.server.schemas.schedules) is only used to raise an error.

Why would we want to replace this line with the server version?
Is the current code no good?

Copy link
Contributor

Choose a reason for hiding this comment

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

@bsignoret Ah, no that's not what I meant, I meant in addition to that, but looking further, keeping it behind TYPE_CHECKING won't work anyway.

However, I think we could simplify this with reflecting type checking like so:

is_server_schema = obj.__class__.__module__ == "prefect.server.schemas.schedules"
if is_server_schema:
    raise ValueError(
        "Server schema schedules are not supported. Please use "
        "the schedule objects from `prefect.client.schemas.schedules`"
    )

Then we can avoid importing any server-side schema. Would you be willing to give that a shot? Tests passed for me locally with that change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for your idea. I've just made the modification and tests are also passed on my side.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice! I'm running our workflows again, and if they pass, I think to future-proof against schedule module name changes and to make it more generic, we probably want to change this last line:
return obj.__class__.__module__.startswith("prefect.server.schemas")

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, hope you don't mind but I'd love to get this in for Thursday's release, so I made this change in cc8dde8

@zzstoatzz zzstoatzz added the maintenance Chores and other work not directly related to the product label May 8, 2024
@serinamarie
Copy link
Contributor

serinamarie commented May 8, 2024

Hi @bsignoret, thanks for opening your first PR(s) with Prefect!

Appreciate these improvements, we were currently working on that this week so it's great timing.

You can fix the failing tests intests/utilities/test_visualization.py by changing this line:
"prefect.flows.visualize_task_dependencies", MagicMock(return_value=None)
to
"prefect.utilities.visualization.visualize_task_dependencies", MagicMock(return_value=None)

at lines 259 and 334.

Additionally, I think you'll need to actually import the client side schedule type schema in the create_minimal_deployment_schedule function:
from prefect.client.schemas.schedules import SCHEDULE_TYPES

I pulled your branch and confirmed that the failing tests pass with those changes, so provided you get a chance to make those changes we can run the workflows here again and see if there's anything else left to fix to get this through!

@bsignoret
Copy link
Contributor Author

Thanks for your feedback!
I've just fixed the failed tests. I've run the tests again on my side, and it looks good now.

However, I'm not sure I understand this modification:

Additionally, I think you'll need to actually import the client side schedule type schema in the create_minimal_deployment_schedule function:
from prefect.client.schemas.schedules import SCHEDULE_TYPES

@serinamarie
Copy link
Contributor

Thanks for your feedback! I've just fixed the failed tests. I've run the tests again on my side, and it looks good now.

However, I'm not sure I understand this modification:

Additionally, I think you'll need to actually import the client side schedule type schema in the create_minimal_deployment_schedule function:
from prefect.client.schemas.schedules import SCHEDULE_TYPES

Hi @bsignoret, after chatting with @bunchesofdonald I think that we want to still keep the server schema but put it behind the TYPE_HINTING condition, like in my comment

Comment on lines 376 to 377
from prefect.runner.server import start_webserver

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 moving this here may be causing the failing tests but haven't checked

Copy link
Contributor

Choose a reason for hiding this comment

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

Hope you don't mind, I'd love to get this in so I'm fixing these failing tests

@serinamarie serinamarie marked this pull request as draft May 17, 2024 00:12
@serinamarie serinamarie force-pushed the optimize_import branch 5 times, most recently from 161190c to f9cee3f Compare May 17, 2024 05:22
@serinamarie
Copy link
Contributor

Update:
Removing the server import (the schedule schema) uncovered some persistent runner tests failures:

  • test_runner_executes_flow_runs
  • test_runner_can_execute_a_single_flow_run
  • test_runner_respects_set_limit

In order to resolve these, I put up a PR to defer an import that was importing, among other things, EventPersister, leading to a runtime error.

Defer import of temporary_database_interface in testing utilities

As well as a PR to Lazily instantiate asyncio.Event in EventPersister for context safety to ensure if we do end up importing the event_persister module in other modules/use it in other tests, we won't run into this same error in the future.

@serinamarie serinamarie changed the base branch from main to all-about-that-infra-base May 17, 2024 15:17
@serinamarie serinamarie deleted the branch PrefectHQ:all-about-that-infra-base May 17, 2024 17:09
@serinamarie serinamarie reopened this May 17, 2024
@serinamarie serinamarie marked this pull request as ready for review May 17, 2024 17:44
@serinamarie serinamarie merged commit 92cca03 into PrefectHQ:all-about-that-infra-base May 17, 2024
39 checks passed
serinamarie added a commit that referenced this pull request May 17, 2024
serinamarie added a commit that referenced this pull request May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Chores and other work not directly related to the product
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants