Conversation
ad4a1ee to
d71f5ee
Compare
…ete Publisher type
d71f5ee to
08a514a
Compare
|
|
||
| struct PublisherWorkflow<WorkflowPublisher: Publisher>: Workflow where WorkflowPublisher.Failure == Never { | ||
| typealias Output = WorkflowPublisher.Output | ||
| struct PublisherWorkflow<Output>: Workflow { |
There was a problem hiding this comment.
Note: This change has the side effect of making this worker only unique against the output of a publisher rather than the concrete publisher type. This can result in two different workers overlapping if they do not specify a key and have the same output type (e.g. Bool).
This is already true for WorkflowReactiveSwift but is a new change for WorkflowCombine
There was a problem hiding this comment.
Some ai suggestions related to this:
I dug further on this and added a repro test showing that this change really does alter runtime behavior: switching between different concrete publisher types with the same output/key no longer forces a resubscribe.
That said, I couldn’t find a strong real-world breakage in
ios-register, andWorkflowReactiveSwiftalready has effectively this behavior today. So I think the important question is whether we wantWorkflowCombineto intentionally match those semantics.If yes, I think this is probably fine, but it should be treated as an explicit behavior change rather than incidental test cleanup:
- keep/add the repro test
- document the caveat similarly to
WorkflowReactiveSwiftIf no, then we should preserve the existing concrete-publisher identity and keep this PR scoped to testing ergonomics.
There was a problem hiding this comment.
Yep - this 100% would break something relying on this, but since we haven't used WorkflowCombine nearly as much as we use WorkflowReactiveSwift it should be relatively safe. The framework will throw an assertion if there's overlap
There was a problem hiding this comment.
I also asked Claude to investigate and found that every usage in register erases to AnyPublisher:
So the behavioral concern — two different concrete publisher types collapsing into the same workflow identity — doesn't apply in practice. Everyone is already erasing to AnyPublisher before calling .running(), which means the concrete type parameter is already AnyPublisher<Output, Never> at runtime today.
|
@codex review |
johnnewman-square
left a comment
There was a problem hiding this comment.
This looks good 👍
|
|
||
| struct PublisherWorkflow<WorkflowPublisher: Publisher>: Workflow where WorkflowPublisher.Failure == Never { | ||
| typealias Output = WorkflowPublisher.Output | ||
| struct PublisherWorkflow<Output>: Workflow { |
There was a problem hiding this comment.
I also asked Claude to investigate and found that every usage in register erases to AnyPublisher:
So the behavioral concern — two different concrete publisher types collapsing into the same workflow identity — doesn't apply in practice. Everyone is already erasing to AnyPublisher before calling .running(), which means the concrete type parameter is already AnyPublisher<Output, Never> at runtime today.
Changes
expectPublisher(producingOutput:key:)API that is generic only over the output of the publisher ratherPublisherWorkflowto only be generic over the output rather than the Publisher typeRationale
The current API shape requires that tests pass in a concrete
Publishertype. This can be quite tedious depending on the context, resulting in having to pass in types likePublishers.Map<AnyPublisher<Bool, Never>, AnyWorkflowAction<SomeWorkflow>>>.This differs from
WorkflowReactiveSwift, for example, which has a workflow that is only generic over the output and has anexpectAPI that only requires providing the output typeChecklist