@mbrandonw I didn't have much time to work on this, but I've managed to prepare an example on a separate branch of my demo project: GitHub - darrarski/tca-ifletstore-effect-cancellation-demo at custom-timer
It uses your lifecycle-reducer concept, but instead to Effect.timer I am using a custom timer publisher I made especially for this example. I have added some ugly prints as well 
To reproduce the issue with publishers not being deallocated after cancel:
- Run the app in a simulator
- Tap "Present Detail" and "Dismiss Detail" couple of times
- Notice following output on the console:
^^^ CustomTimerPublisher.init (1)
^^^ CustomTimerSubscription.init (1)
^^^ CustomTimerSubscription.cancel
^^^ CustomTimerSubscription.deinit (0)
^^^ CustomTimerPublisher.init (2)
^^^ CustomTimerSubscription.init (1)
^^^ CustomTimerSubscription.cancel
^^^ CustomTimerSubscription.deinit (0)
^^^ CustomTimerPublisher.init (3)
^^^ CustomTimerSubscription.init (1)
^^^ CustomTimerSubscription.cancel
^^^ CustomTimerSubscription.deinit (0)
The number in parentheses is a count of instances in memory. It looks like the subscription is correctly canceled and deinitialized, but not the publisher.
I've also tried to use Xcode's memory debugger to investigate what holds the publisher instances in the memory, but unfortunately, I didn't found any valuable hints beside I confirmed the publishers were not deinitialized.
Perhaps there is something wrong with my custom publisher implementation, but I am not sure about it. It's rather simple.
Here is a link to all changes in the code I made for this example: Comparing solution-lifecycle...custom-timer · darrarski/tca-ifletstore-effect-cancellation-demo · GitHub
UPDATE
It looks like wrapping the custom publisher in Deferred before converting it to Effect solves the issue with retained publishers. I pushed the changes here: Wrap custom publisher in Deferred to fix the issue with retained publ… · darrarski/tca-ifletstore-effect-cancellation-demo@7cdc0c6 · GitHub
I am still not sure what actually caused the problem. It could be connected with how Effect cancellables are stored, or perhaps my custom publisher implementation is missing something.
UPDATE 2
While my custom publishers are no longer retained (which seems to be ok), now the Deferred publishers are still in the memory (wrapped in PublisherBox), so it looks like the issue is not completely solved 