I’ve read quite a few articles (both here and elsewhere) about singletons. Often not the best design pattern, but sometimes necessary because that’s just inherently the nature of the system you’re interacting with. One thing I’ve never seen mentioned is the issue of crate versions! Things like lazy_static
, or static Cell
, or static mut
, or whatever solution, as far as I can tell all have a single common problem: you can have two simultaneous instances of the object if your depgraph pulls in two versions of the crate that contains the lazy_static
or whatever (because e.g. your binary and one of its dependencies depend on semver-incompatible versions).
Has anyone come up with a solution that handles this?
I think failing to compile would be a reasonable outcome. After all, the proper way in which the singletons should be used is that e.g. my_binary
and my_intermediate_library
both depend on my_library_with_a_singleton
, but my_binary
does the singleton-take operation and my_intermediate_library
only accepts the singleton passed in by the caller. If my_binary
and my_intermediate_library
end up depending on different versions of my_library_with_a_singleton
, then this properly written code will fail to compile because my_library_with_a_singleton(v1.0)::Singleton
is not the same type as my_library_with_a_singleton(v2.0)::Singleton
and therefore cannot be passed as a function parameter in the relevant place.
The concern is that, if my_intermediate_library
were written to take the singleton itself instead, you’d end up with this perverse outcome where if only a single version is pulled into the depgraph then everything blows up at runtime (as it ought to, since two things are trying to take the singleton), but if two versions are pulled in, then nothing explodes and you get whatever badness the singleton was trying to prevent.