Excellent. Thank you, Axel, for the full briefing, and backstory, and especially the advice to use a very stable internal style package to pro-actively avoid the situation. I'll close out that ticket. On Sunday, May 11, 2025 at 8:07:50 AM UTC+1 Axel Wagner wrote:
> The only case where you can reasonably say that there are "two versions of > the same package" in a build, is if they are in different major versions of > the same module¹, say example.com/foo/v2 and example.com/foo/v3. > In that context, you have control over both versions. You can guarantee > that they use the same mutex, by having them refer to each other. That is, > you would implement v2 in terms of v3, that way ensuring that even if some > code still imports v2, they still ultimately use the v3 mutex. > However, there is a problem: You can only implement v2 in terms of v3, > once that exists. So you might introduce v3 while v2.23 is out and then > have to introduce v2.24 to be implemented in terms of v3. But some clients > might still import an v2.23. If those builds than *also* add v3, you end up > with two mutexes. > The way around that is to have both of those refer to a third package, > which contains the mutex. So you would have example.com/internal/mutex > (which lives in its own module example.com/internal) which contains a > mutex and have example.com/foo/v...@v2.24 > <http://example.com/foo/v2@v2.24> import that to refer to the mutex. You > can then wait until all importers have upgraded to v2.24. And when you then > build example.com/foo/v3, it also imports example.com/internal/mutex. > That way, all builds use a single mutex. > Of course, there is still a rest risk of clients not upgrading from v2.23 > at all. But unfortunately, if you can't *somehow* prepare the earlier > version and rely on that preparation to propagate, you are out of luck, I > believe. > > I don't believe there is a trick to statically enforce that two packages > can not be imported at the same time (neither in the general case, nor in > the special case that they are in two major versions of the same module). > In a way, that's by design. It would be undesirable, for the import of one > package to be able to break the import of a different package. Because if > you *could* get into a situation where package A and package B are mutually > exclusive, you could have a module dependency graph E->C->A, E->D->B and > then the author of module E could do nothing to fix their build (as they > can not force the authors of either module C or module D to change their > imports, in a timely manner). Preventing these kinds of situations was a > major design goal of Go modules. Which is why it's possible to use two > major versions of a module in the same build in the first place. > > You could potentially dynamically enforce that there are no two major > versions of the same module used in one build. A simple (somewhat limited) > way would be to use `runtime/debug.BuildInfo` to check which modules are > included in an `init` function and panic/exit if there is a conflict. But I > would strongly warn against that. Because as I said, making this impossible > statically was done for a reason and those reasons still apply if you do it > dynamically - just that it's even more frustrating, because you will only > notice *after* building and potentially deploying the binary. > > So, I think the real advice is: Don't. Do not rely on the assumption, that > the same mutex is used. If nothing else, you can't prevent someone from > forking your module and someone else to end up with both the original in > the fork in the build. And if your case would break, that would break as > well. > > [1] Some may argue that this is not "the same package", as different major > versions can be considered different modules and because Semantic Import > Versioning is intentionally part of the module design. However, I think in > the context of the question, that's still reasonably "the same package". > > On Sun, 11 May 2025 at 06:45, Jason E. Aten <j.e....@gmail.com> wrote: > >> Is there a way to insure I've only got one version >> of a package in a build? I need to make sure >> a single mutex is used by all goroutines. >> >> Detailed back story is here: >> https://github.com/golang/go/issues/73665 >> >> -- >> > You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com. >> To view this discussion visit >> https://groups.google.com/d/msgid/golang-nuts/bdc40509-6b71-469e-82ce-c5fb4a64211bn%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/bdc40509-6b71-469e-82ce-c5fb4a64211bn%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/6994438a-295b-480f-81e6-ef1081e4f3dbn%40googlegroups.com.