Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Custom slot supplier #690

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

Merged
merged 16 commits into from
Nov 20, 2024
Merged

Custom slot supplier #690

merged 16 commits into from
Nov 20, 2024

Conversation

Sushisource
Copy link
Member

What was changed

Add user-implementable slot suppliers

Why?

Parity. Cool feature.

Checklist

  1. Closes

  2. How was this tested:
    Added tests

  3. Any docs updates needed?
    Yes, docs to follow when .NET is done

@Sushisource Sushisource requested a review from a team as a code owner November 15, 2024 22:53
@Sushisource Sushisource force-pushed the custom-slot-supplier branch 2 times, most recently from 4889426 to aaa7e45 Compare November 15, 2024 23:08
@Sushisource
Copy link
Member Author

My only remaining concern is I will sometimes see lines like this on test shutdown:

Task was destroyed but it is pending!
task: <Task pending name='Task-27' coro=<_ErrorLoggingSlotSupplier.reserve_slot() done

I also occasionally will see them for stuff I didn't touch, though. AFAICT this is simply whining that a cancelled task didn't get one more go in the event loop to have the CancelledError it raised propagate up, but I'm not sure if that's really a real issue or just the tests exiting directly following worker shutdown.

@@ -6,9 +8,22 @@
from typing_extensions import TypeAlias

import temporalio.bridge.worker
from temporalio.bridge.worker import (
ActivitySlotInfo,
CustomSlotSupplier,
Copy link
Member

Choose a reason for hiding this comment

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

Can we define this and all its other public API outside of the bridge area? Here in this file should be fine. Note we did similar for things like temporalio.runtime.BufferedMetric as a "protocol" (i.e. interface) noting that it had to match the Rust form of a bridge class impl. If there are things we need to work out with imports we can.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah it's kind of pain because of circular import issues. I'll see if I can move it but I'm worried it means duping a bunch of stuff

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

tokio::runtime::Builder::new_multi_thread(),
TokioRuntimeBuilder {
inner: tokio::runtime::Builder::new_multi_thread(),
lang_on_thread_start: Some(move || {
Copy link
Member

Choose a reason for hiding this comment

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

Can you help me understand this a bit? Looking at https://github.com/awestlake87/pyo3-asyncio/blob/master/src/tokio.rs I don't see where they are building a Tokio runtime w/ custom thread starter to add task locals for every thread. I wonder if we can just make/set the task locals with the event loop inside the one place they are needed later? The current event loop is available there too. I also see they use https://docs.rs/tokio/latest/tokio/macro.task_local.html, unsure if we could too.

Copy link
Member Author

Choose a reason for hiding this comment

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

They don't because I think it's built mostly on the assumption that it's Python calling into Rust and not the other way around, so any time and event loop is needed it already exists. That's not the case here, because we call into Python from whatever arbitrary thread in the Tokio runtime and that thread may not have any loop available on it, so we need to re-use the existing one (which also needs to be the same as the main one to avoid surprise issues with different loops trying to use things that were created on the main/another loop).

loop inside the one place they are needed later

What one place are you thinking of? Task locals are I think just going to mean we call this way more frequently than thread locals.

Copy link
Member

@cretz cretz Nov 18, 2024

Choose a reason for hiding this comment

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

What one place are you thinking of?

Ah, yes, my mistake. So question, can any of these Python references information be captured and moved into the CustomSlotSupplierOfType? I admit I haven't dug into this, but I know I found in Ruby a way to keep "opaque" references that needed the GIL to use them, but were still Send/Sync so that I could move around (and they were prevented from being collected by Python while still having a reference in Rust).

If that's possible, I think we should put the TaskLocals on the CustomSlotSupplierOfType. Granted that assumes it's created with an event loop intact, but that should be an ok assumption I think. Actually, that's not something we should assume with Runtime now that I think about it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, might be able to do that. I'll take a look

Copy link
Member Author

Choose a reason for hiding this comment

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

Done. Honestly not sure it's any better, really, but done regardless

Copy link
Member

Choose a reason for hiding this comment

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

True, though it is nice that it's worker specific and not actually setting any task locals

@Sushisource Sushisource force-pushed the custom-slot-supplier branch 2 times, most recently from 934de2c to 6ca80a5 Compare November 18, 2024 22:33
@Sushisource Sushisource force-pushed the custom-slot-supplier branch 4 times, most recently from 4015670 to 9f0f51d Compare November 18, 2024 23:34
Copy link
Member

@cretz cretz left a comment

Choose a reason for hiding this comment

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

Nothing blocking

tokio::runtime::Builder::new_multi_thread(),
TokioRuntimeBuilder {
inner: tokio::runtime::Builder::new_multi_thread(),
lang_on_thread_start: Some(move || {
Copy link
Member

Choose a reason for hiding this comment

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

True, though it is nice that it's worker specific and not actually setting any task locals

}
}

fn available_slots(&self) -> Option<usize> {
Copy link
Member

Choose a reason for hiding this comment

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

I assume there is no value in allowing users to define this, at least not at this time.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, there's not at the moment

except asyncio.CancelledError:
raise
except Exception:
logger.warning(
Copy link
Member

Choose a reason for hiding this comment

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

If you'd rather, instead of logging and having a global logger, can call https://docs.python.org/3/library/warnings.html#warnings.warn instead. We do this in other places for should-not-happen things without relying on them setting up logging.

Copy link
Member Author

Choose a reason for hiding this comment

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

Decided not to do this since formatting for the user thrown exception is not nearly as nice w/ the stack trace not being shown whereas logging does

@Sushisource Sushisource enabled auto-merge (squash) November 20, 2024 18:33
@Sushisource Sushisource merged commit 042e088 into main Nov 20, 2024
12 checks passed
@Sushisource Sushisource deleted the custom-slot-supplier branch November 20, 2024 19:44
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