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

Live reload per-host clients #219

Merged
merged 2 commits into from
Jul 1, 2024
Merged

Live reload per-host clients #219

merged 2 commits into from
Jul 1, 2024

Conversation

sfackler
Copy link
Member

@sfackler sfackler commented Jun 6, 2024

Before this PR

Each client in a per-host-clients context was static - its internal configuration would not live reload based on config changes even when that host was still present. This makes it hard to use in some contexts where there are background tasks happening on a per-host basis.

After this PR

==COMMIT_MSG==
Each per-host client now live reloads as long as that host remains in the service configuration.
==COMMIT_MSG==

Closes #218

@sfackler sfackler requested a review from a team June 6, 2024 19:25
@changelog-app
Copy link

changelog-app bot commented Jun 6, 2024

Generate changelog in changelog/@unreleased

What do the change types mean?
  • feature: A new feature of the service.
  • improvement: An incremental improvement in the functionality or operation of the service.
  • fix: Remedies the incorrect behaviour of a component of the service in a backwards-compatible way.
  • break: Has the potential to break consumers of this service's API, inclusive of both Palantir services
    and external consumers of the service's API (e.g. customer-written software or integrations).
  • deprecation: Advertises the intention to remove service functionality without any change to the
    operation of the service itself.
  • manualTask: Requires the possibility of manual intervention (running a script, eyeballing configuration,
    performing database surgery, ...) at the time of upgrade for it to succeed.
  • migration: A fully automatic upgrade migration task with no engineer input required.

Note: only one type should be chosen.

How are new versions calculated?
  • ❗The break and manual task changelog types will result in a major release!
  • 🐛 The fix changelog type will result in a minor release in most cases, and a patch release version for patch branches. This behaviour is configurable in autorelease.
  • ✨ All others will result in a minor version release.

Type

  • Feature
  • Improvement
  • Fix
  • Break
  • Deprecation
  • Manual task
  • Migration

Description

Each per-host client now live reloads as long as that host remains in the service configuration.

Check the box to generate changelog(s)

  • Generate changelog entry

Some(e) => {
for e2 in errors {
warn!("error reloading per-host clients", error: e2);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

The error handling here is all deferred so we don't lose track of state when a subset of clients have issues updating. I don't expect that to be a common case but wanted to make sure we handled it.

Choose a reason for hiding this comment

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

Where are we updating the state in this method? As in, what would be lost if we returned the error early here https://github.com/palantir/conjure-rust-runtime/pull/219/files#diff-6d2572eabc17f7b3329877aef40ce0daeebbc8cb310e2c5394e530c28b6d42f4R446?

Copy link
Member Author

Choose a reason for hiding this comment

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

We'd forget about some of the clients so the next refresh we'd end up making new ones for those hosts instead of reloading the old ones.

override_host_index: Option<usize>,
) -> Result<Client, Error>
where
T: Borrow<StateBuilder> + 'static + Sync + Send,

Choose a reason for hiding this comment

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

I'm trying to understand how this Borrow type works (and why it's useful vs. just using &T).

I read about it here https://doc.rust-lang.org/std/borrow/trait.Borrow.html. Is it sort of like String, in that you can just pass T directly, but it can be implicitly cast to &T (or &str) because it implements Borrow?

Copy link
Member Author

Choose a reason for hiding this comment

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

It has some extra requirements that are used in some other places, but the key thing in this context is that it's a trait implemented by both T and Arc<T> that lets you get a &T. This function is called in 2 places. The per-host stuff needs to store the state builder in an arc, while the normal stuff up in client_inner doesn't and this bound makes both work.

}

Ok(PerHostClients { clients })
client_handles = new_client_handles;

Choose a reason for hiding this comment

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

Where is client_handles used?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's used up on line 429.

Choose a reason for hiding this comment

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

I think where I'm confused is this (line 457) is outside of the loop. So how does our reassignment here affect line 429?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh yeah, it's not updating it for the next loop iteration, it's updating it for the next call to this closure (i.e. the next time the service config changes)

fn raw_client<T>(
state_builder: T,
service_config: Refreshable<ServiceConfig, Error>,
override_host_index: Option<usize>,

Choose a reason for hiding this comment

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

I see this is part of the CachedConfig type. It says it Overrides the hostIndex field included in metrics. What is the purpose of that?

Copy link
Member Author

Choose a reason for hiding this comment

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

There are some metrics which are tracked for each URI separately with a hostIndex field. Normally that's determined by the index of the URI in the URIs list of the ServiceConfig, but the per-host logic ends up making a separate ServiceConfig for each URI. Without the override each of those would end up using hostIndex 0 so the metrics would all get merged.

Some(e) => {
for e2 in errors {
warn!("error reloading per-host clients", error: e2);
}

Choose a reason for hiding this comment

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

Where are we updating the state in this method? As in, what would be lost if we returned the error early here https://github.com/palantir/conjure-rust-runtime/pull/219/files#diff-6d2572eabc17f7b3329877aef40ce0daeebbc8cb310e2c5394e530c28b6d42f4R446?

@sfackler sfackler requested a review from a team June 26, 2024 19:42
@sfackler sfackler merged commit f460964 into develop Jul 1, 2024
4 checks passed
@sfackler sfackler deleted the per-host-refresh branch July 1, 2024 15:18
@autorelease3
Copy link

autorelease3 bot commented Jul 1, 2024

Released 5.1.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Per host clients should be live reloaded
3 participants