The singleflight package started life in internal/singleflight and then moved to golang.org/x/sync/singleflight, and the two have had slightly divergent development histories since. It's getting kinda messy. Their APIs have even somewhat diverged.

I just tried to re-unify them and delete internal/singleflight from std, but we can't use mod/vendor packages during bootstrap.

/cc @ianlancetaylor

Comment From: gopherbot

Change https://golang.org/cl/174080 mentions this issue: src/vendor: add golang.org/x/sync/singleflight, delete internal/singleflight

Comment From: cuonglm

Another step to re-unify them is:

  • Adding a new method to golang.org/x/sync/singleflight to report something like this https://github.com/golang/go/commit/6c877e5da7ab14f0d8a206c09f24cf51fbbc393a#diff-64cfc9b51215a4e84f98e7a67cfa800a

  • Change golang.org/x/sync/singleflight to behave the same as internal/singleflight.

I vote for 1st point, 2nd point will break current user of golang.org/x/sync/singleflight out there. How do you think @bradfitz ?

Comment From: bradfitz

We can't break (change) the x/sync/singleflight public API.

We can add a new method, though.

Comment From: tarndt

If github.com/golang/sync another fork or is that just a clone of golang.org/x/sync? I've been unsure which should be imported.

Comment From: cuonglm

@tarndt Use golang.org/x/sync, it's custom import path for github.com/golang/sync https://github.com/golang/sync/blob/master/singleflight/singleflight.go#L7

Comment From: gopherbot

Change https://go.dev/cl/423654 mentions this issue: net: avoid relying on singleflight.Group.DoChan to detect hook called

Comment From: gopherbot

Change https://go.dev/cl/423655 mentions this issue: internal/singleflight: make DoChan only return Result channel

Comment From: bradfitz

@cuonglm, rather than delete internal/singleflight, how about taking advantage of its private nature and give it generics like we did in our https://pkg.go.dev/tailscale.com/util/singleflight fork?

The std can use it with types instead of the any boxing.

(Unless you want to wait for https://github.com/golang/go/issues/53427; but that could be a long time)

Comment From: cuonglm

@cuonglm, rather than delete internal/singleflight, how about taking advantage of its private nature and give it generics like we did in our https://pkg.go.dev/tailscale.com/util/singleflight fork?

The std can use it with types instead of the any boxing.

(Unless you want to wait for https://github.com/golang/go/issues/53427; but that could be a long time)

That sounds interesting, but I think we still need to wait until we bump the bootstrap version to 1.18 at least, for supporting generic?

The main motivation is that we should unify them, so we need to maintain one version only.

Comment From: cuonglm

That sounds interesting, but I think we still need to wait until we bump the bootstrap version to 1.18 at least, for supporting generic?

Ah never mind, we don't have to, since when singleflight is only used in std, not during bootstrap tools.

Comment From: gopherbot

Change https://go.dev/cl/425187 mentions this issue: all: switch singleflight to use generic

Comment From: cuonglm

@bradfitz See CL 425187 for adding generic to singleflight. We can keep it then, until #53427 accepted.

Comment From: arvenil

Any reason singleflight is not in standard library sync package?