Skip to content

Conversation

yuandrew
Copy link
Contributor

@yuandrew yuandrew commented Oct 14, 2025

What was changed

Send plugin names over to core for worker heartbeating.

Updated Core to latest main, 9e9a461.

Updated test to validate replacing clients with a client from a different runtime is invalid.

Why?

Worker heartbeating

Checklist

  1. Closes

  2. How was this tested:

Added tests for plugin name propogation, and runtime options configuration

  1. Any docs updates needed?

Note

Forward plugin names to Core for worker heartbeating, introduce runtime options (incl worker heartbeat), tighten client replacement to same-runtime, and bump Core/deps (prost/tonic/OTel).

  • Worker/Plugins:
    • Send plugin names to Core via WorkerConfig.plugins (mapped to PluginInfo); add skip_client_worker_set_check flag; propagate plugins from client to worker; tests validate propagation and Core forwarding.
    • replace_client now returns error on failure; Python Worker.client setter enforces same-runtime clients.
  • Runtime:
    • Introduce RuntimeOptions (Python/Rust) and change init_runtime to accept options; support worker_heartbeat_interval/heartbeat_interval wiring; tests for conversion/validation.
  • Client/Core bridge:
    • Switch to TemporalServiceClient (drop metrics wrapper); adjust tonic imports.
    • Update replay worker to pass plugins and skip worker-set check.
  • Dependencies/Core:
    • Upgrade prost/tonic/opentelemetry*; add tonic-prost*, dyn-clone; bump uuid; update sdk-core submodule.
  • Tests/Minor:
    • Adjust metrics assertions; add fixtures to default skip_client_worker_set_check; cleanups.

Written by Cursor Bugbot for commit efb91e4. This will update automatically on new commits. Configure here.

@yuandrew yuandrew marked this pull request as ready for review October 21, 2025 01:04
@yuandrew yuandrew requested a review from a team as a code owner October 21, 2025 01:04
self,
*,
telemetry: Optional[TelemetryConfig] = None,
runtime_options: Optional["RuntimeOptions"] = None,
Copy link
Member

Choose a reason for hiding this comment

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

I think you should either inline runtime options into kwargs here, or have user-facing runtime options not include telemetry. To have telemetry in both places is confusing.

Copy link
Contributor

@tconley1428 tconley1428 Oct 21, 2025

Choose a reason for hiding this comment

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

I think I would just take the two components here and then build the runtime options. Only because of the backwards compatibility.


// Create core runtime which starts tokio multi-thread runtime
let mut core = CoreRuntime::new(
let mut runtime_options_build = RuntimeOptionsBuilder::default();
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 would be ideal for the variable to be immutable and do the builder args in a chain.

RuntimeOptionsBuilder::default().telemetry_options(...).heartbeat_interal(ms.map(Duration::from_millis))

Or something

activity_task_poller_behavior: PollerBehavior
nexus_task_poller_behavior: PollerBehavior
plugins: Sequence[Plugin]
skip_client_worker_set_check: bool
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't love the addition of this to the very public worker config. This was due to validation issues in the tests, correct? How much work do we think it would be to actually just fix those issues? Is there any place where it is really meaningful?

)
.nexus_task_poller_behavior(conf.nexus_task_poller_behavior)
.plugins(
conf.plugins
Copy link
Contributor

Choose a reason for hiding this comment

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

So, something that will need some discussion here. This PR reports worker plugins. We should discuss whether that is really what we intend. Plugins which exist only in the client and not the worker will be completely invisible. That could potentially be changed here at least for plugins in clients used by workers, though not generally for any client. I think that was something we didn't really think through when we decided to go with heartbeat as a carrier for this information, but maybe we conclude that is fine.

Typescript will be a bit more complicated as well with its additional plugin types.

"""Python representation of the Rust struct for runtime options."""

telemetry: TelemetryConfig
worker_heartbeat_interval_millis: Optional[int] = 30_000 # 30s
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want the defaults defined by each language, or does this make more sense to take optionally into core and default there? Since this is optional but with a default number, does that mean overriding with None disables heartbeating?

1
),
plugins=[plugin.name() for plugin in self.plugins],
skip_client_worker_set_check=True,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this important? Will the replayer break if this is False?

self,
*,
telemetry: Optional[TelemetryConfig] = None,
runtime_options: Optional["RuntimeOptions"] = None,
Copy link
Contributor

Choose a reason for hiding this comment

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

I would probably just move the type definition up so you don't have to do the "Type" thing.



@pytest.fixture(autouse=True)
def _force_worker_skip_client_set(monkeypatch):
Copy link
Contributor

Choose a reason for hiding this comment

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

Not really a force if we are just setting the default.

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.

3 participants