I posted the original question here: https://github.com/atom/atom/issues/8226, as a issue, but somehow I’m not really satisfied with the “It’s not a bug, it’s a feature” answer. Not because I had to redo some code in my packages, but because I somehow found a scenario that this would really be a problem:
In Atom 1.0.3, providers and consumers API were made async - this means that, when we activate a package, if that package consumes a service, the providers of that service may, or may not, be already activated. The most problematic way, in my opinion, of this decision is that, somehow, “consumer” and “provider” creates a kind of dependency with the packages - the consumer depends on providers. In almost every other case, when we depend on another service, that service is loaded first - but now, it’s not the case. This leads to code that must adapt to the case of providers being fired after the consumer was loaded, but will only be used in a single case - the moment that the package is activated. It is more burden to package creators that, indeed, will only be used once (but things will break if this code is not properly treated).
I found a specific edge-case that is when package A is a consumer, package B is a provider and a consumer, and package C is a provider - in this case, package A should now that B is a provider and a consumer, because package B will receive information from C and forward to A. Or, in a more specific case, where’s what I said in the issue (real use-case here, I’m really trying to implement it):
The edge-case I found is the following: in my Everything plugin, I bind a searcher to a group of providers. So, the user types a query, the searcher fires this query to registered providers, then it awaits for providers to return. I’m trying to implement a “find symbols”, like Sublime’s, when you type @, it finds the symbols in the current file.
What I wanted to do, thought, is to this “find symbols” to be a consumer of another kind of providers - for now, let’s call then “Parsers”. This would be incredible for spec files, for instance, when there are no method definitions, but you could navigate through every testcase and every method - you would only need to register a new provider.
Ok, but now, the “Symbols” provider depends on “Parsers”, but it cannot know previously how many, and who they are. He will pass to Everything just what he knows it exists, and Everything will show just that - but, of course, a moment later a new Parser is registered, but the provider already sent information to its consumer…
I think this could become a big problem when there are consumers that depends on providers that are consumers too… it breaks a kind of “principle of less surprise”, that a user thinks that if his package depends on another, the other will already be loaded.
I think that, in the previous case, the problem is mostly because I’ll need to implement a kind of “this provider is not fully loaded yet and can send me more items in my search”, but the provider itself does not know it’s not fully loaded. With the API that we have today, there’s simply no way of solving this problem…