Skip to content

proposal: x/sync/singleflight: add a method for per-caller post-processing of shared result  #56349

Open
@costela

Description

@costela

Background

In order to safely deal with some classes of shared resources that can be acquired via a singleflight group (anything that requires explicit cleanup/freeing; files, shared buffers, etc), there is need for a mechanism to account for all goroutines that received a reference to the shared resource.

It is not sufficient to perform this accouting after the singleflight call returns, since any single waiting goroutine may complete its work on the shared resource before other goroutines start, leading to misbehavior.

Proposal

To solve this missing functionality, there were suggestions (not converted to proposals) to expose singleflights internal count of duplicated calls.

I propose a different approach, inspired by this comment: extend the singleflight.Group API to include a second function parameter, called by every duplicated caller.

E.g.:

sg := &singleflight.Group{}
sg.DoShared(
	"somekey",
	func() (interface{}, error) {
       	// acquire shared resource
	},
	func(shared interface{}, err error) {
		// perform arbitrary per-caller post-processing;
		// guaranteed to run before any caller returns.
	},
)

Pros:

  • explicit
  • versatile
  • has no impact on existing usage
  • leaves error handling to the consumer (with the exception of panics)

Cons:

  • increases API surface area
  • less intuitive API

Relates to golang/sync#9 and golang/sync#20

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Incoming

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions