❓ Question: Service vs Module-level Singleton for Polling in Ember

We are building a suite of products with module-based components, where each module is designed to be reusable across multiple products.

In one such module, we need to poll the server to track the status of certain processes. Multiple components within this module depend on this polling mechanism.

To handle this, I created a shared class inside the module’s component folder and exported a singleton instance. Components in the module import this instance and subscribe using a unique ID (which is the process ID). Whenever the status changes, the corresponding callback is triggered. This approach is working well so far.

However, I recently came across the recommendation in Ember.js that shared state or long-lived data should be managed using services.

This raised a few questions for me:

  1. My understanding is that services are primarily used to share data across the entire application.
  2. In my case, the polling logic is only relevant to a specific module, not the whole app.
  3. If I convert this into a service, I might end up creating many module-specific services, which feels excessive.

My Questions

  1. Is it a best practice in Ember to always use services for shared state like polling?

  2. Is my current approach (module-level singleton) acceptable in this scenario?

  3. If I use services for module-specific logic, is having many such services considered okay?

Your feedback would be really helpful.

IMO it depends on the “lifetime” of the state/class., and also how you want to get the state into the components that need it.

If the state should live as long as the app then a service is the natural choice. If the state is really only useful as long as a certain thing/things are rendered then it might make more sense as state that is owned by a component or route (which i guess is basically a component these days). If each “module” has a single parent component that it renders then that’s an easy owner for your shared state (this is also similar to the provider pattern).

If the state works better as a dependency injection (each component can inject the service it needs) then a service might be the right choice. Otherwise you’re left with args/props which can get messy in complex component trees.

Another factor is the service patterns may change a little bit in the future (i’m not certain where that conversation stands atm but i do think the resolver based service injection is considered legacy).

So all that to say there are factors to weigh but I don’t think there’s a super cut and dry answer and it’s up to you. If you find that what you’re doing is working really well it seems reasonable to me. But if you think that services would be cleaner because of the “lifetime” or the dependency injection bits then that might be the way to go.