-
Notifications
You must be signed in to change notification settings - Fork 33
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
feat: add workflow client updater for updating workflow client #258
Conversation
@@ -4449,7 +4448,58 @@ await foreach (var evt in handle2.FetchHistoryEventsAsync()) | |||
worker.Client = otherEnv.Client; | |||
|
|||
// Now confirm the other workflow has started | |||
await AssertHasEventEventuallyAsync(handle1, e => e.WorkflowTaskCompletedEventAttributes != null); | |||
await handle2.AssertHasEventEventuallyAsync(e => e.WorkflowTaskCompletedEventAttributes != null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was a typo from the original PR? I changed the test case to check handle2
instead of handle1
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks! (hopefully my typo here didn't cause the test to pass when it shouldn't have)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope, tests passed fine!
|
||
namespace Temporalio.Tests | ||
{ | ||
public static class WorkerAssertionExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to re-use some of these methods that were originally in WorkflowWorkerTests.cs
in TemporalWorkerServiceTests.cs
, so I pulled them out into extension methods here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you instead add them to the AssertMore
class that already exists (and remove the Assert
prefix of the methods and not make them extension methods)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! My original thought was that this was best in the hosting extension only since those creating workers directly don't need this abstraction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think any of this is needed in the Temporalio
project. This is a generic host problem only. Those making workers directly can just use the Client
setter. I also don't think an interface is needed unless you really think it's important for testing (even then not sure the event handler needs to be part of the interface). Also, even though it's a mouthful, I'd call this TemporalWorkerClientUpdater
w/ the Temporal
prefix to match the worker class name for discoverability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, done.
I don't think a lack of an interface hampers testing, since the implementation has no dependencies
|
||
namespace Temporalio.Tests | ||
{ | ||
public static class WorkerAssertionExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you instead add them to the AssertMore
class that already exists (and remove the Assert
prefix of the methods and not make them extension methods)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Some more comments about visibility and general simplification I think we can do
src/Temporalio.Extensions.Hosting/TemporalWorkerClientUpdateSubscriber.cs
Outdated
Show resolved
Hide resolved
src/Temporalio.Extensions.Hosting/TemporalWorkerClientUpdater.cs
Outdated
Show resolved
Hide resolved
src/Temporalio.Extensions.Hosting/TemporalWorkerClientUpdater.cs
Outdated
Show resolved
Hide resolved
src/Temporalio.Extensions.Hosting/TemporalWorkerServiceOptions.cs
Outdated
Show resolved
Hide resolved
private readonly TemporalClientConnectOptions? newClientOptions; | ||
private readonly ITemporalClient? existingClient; | ||
private readonly TemporalWorkerOptions workerOptions; | ||
private readonly TemporalWorkerClientUpdater? workerClientUpdater; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private readonly TemporalClientConnectOptions? newClientOptions; | |
private readonly ITemporalClient? existingClient; | |
private readonly TemporalWorkerOptions workerOptions; | |
private readonly TemporalWorkerClientUpdater? workerClientUpdater; | |
private readonly ITemporalClient? existingClient; | |
private readonly TemporalWorkerServiceOptions workerOptions; |
Now that we are basically storing the three separate pieces anyways, let's just store the full service options as one field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's not really a good way I've found to handle the constructors that take in TemporalWorkerOptions
directly (from some testing, cloning is not contravariant).
I don't know of a better way to convert an instance of TemporalWorkerOptions
into TemporalWorkerServiceOptions
other than writing a direct translation method, which imo is not desirable for maintenance. Do you have a suggestion?
I think it would be easier if TemporalWorkerServiceOptions
was composed of TemporalWorkerOptions
instead of directly inheriting from it, but that is a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see now that we have multiple constructors for this TemporalWorkerService
that accept partial forms. Ok, can ignore my comment and leave these as separate fields.
tests/Temporalio.Tests/Extensions/Hosting/TemporalWorkerServiceTests.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Will merge a bit later today.
lock (clientLock) | ||
{ | ||
OnClientUpdatedEvent += eventHandler; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like locking technically not required per https://stackoverflow.com/questions/22825117/is-it-thread-safe-to-register-for-a-c-sharp-event, but this is fine
What was changed
Added an optional
WorkerClientUpdater
parameter toTemporalWorkerOptions
. If specified, the worker will subscribe to worker client changes from the updater, and update its underlying worker client.Why?
This allows users to update the underlying
IWorkerClient
on running workers without having to restart the workers entirely when using the DI extension.Checklist
Closes
[Feature Request] Support worker client update when using generic host #257
How was this tested:
Added test cases both for manual instantiation and DI based instantiation.
I updated the README of the hosting extension. I didn't update the README of the regular library as worker refresh is not documented there, and I don't really think there is less of a reason to use the worker client updater if not using DI.