I believe this pattern is generally the right thing to do, actually.
Libraries should almost never choose to own their own
EventLoopGroup. This is because it's highly valuable to have an extremely small number of groups in an application; in fact, for many applications you may want only one.
To understand this better, consider a large application that combines Vapor, your StatsD client, and some other hypothetical protocol clients such as Redis and HTTP. Each of these libraries may be separate, from a separate source.
If each library initialises its own event loop groups, then each library has a completely isolated set of threads to handle its I/O. If one of these libraries is busiest (e.g. Vapor, handling all inbound load), the threads for that library will be extremely busy, while threads for the other libraries will be less busy. In this kind of world, you want one of two things:
- You may want separate groups for each library, to isolate them from each other. That's fine, but in this case you'd want more threads for Vapor than for, say, Redis. How can the library know this?
- You may want to have one, large group of threads, handling heterogenous load. This means that a particularly "hot" connection (e.g statsD) can potentially starve the connections sharing the loop with it, but the flip side is that quiet connections (e.g. HTTP client connections) can take up small slices of idle time on the otherwise busy loops.
Exactly what distribution of loops is best for an application is not generally possible for a library author to know ahead of time. As a result, the best thing to do is to let the application author decide. You can certainly publish documentation that provides suggested configurations, and potentially even helpers if obtaining this configuration is complex, but in general I think this is the basic API to use.