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.

Reply via email to