How-to: Chain behaviours?

Hi all. I’m still pretty new to Elixir and completely new to Elixir metaprogramming. Before I dig deeper into metaprogramming I wanted some quick feedback to ensure I’m on the right track.

I have GenStages and I’d like them to shutdown if the last subscriber has canceled. This is completely doable by sprinkling logic within handle_subscribe and handle_cancel and storing subscriber_count within the module’s state. Doable, but kind of ugly and repetitive.

I think I’d like to extract this subscriber counting logic into a behavior and use this new behavior in conjunction with the GenStage behavior. Is this the proper strategy?

Would something like:

use GenStage
use GSSubscriberTracking, all_subscribers_canceled: :shutdown 

be the right way? I was planning to use/abuse the process dictionary so that my behavior’s internal state doesn’t bleed into the state passed around via the GenState callbacks. Is that a proper strategy?

Original plan:

Have a behavior that wraps the GenStage behavior for handle_subscribe and handle_cancel callbacks. Maybe this possible but not preferable.

New plan:

Instead of a behavior that would transparently intercept and change the values coming from handle_cancel. Maybe simply providing a behavior that could track subscribers and make a function available that would allow the explicit logic within handle_cancel to be cleaner.

All thoughts/tips appreciated.

1 Like