NOTE

sync.singleflight

A singleflight DoChan usage example with context timeout and shared results.

Go1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. Usage

package main

import (
	"context"
	"fmt"
	"time"

	"golang.org/x/sync/singleflight"
)

type data string

func main() {
	// Set a context that times out after one second
	d := time.Now().Add(1 * time.Second)
	ctx, cancel := context.WithDeadline(context.Background(), d)
	defer cancel()

	var ret singleflight.Result
	var g singleflight.Group
	key := "https://weibo.com/1227368500/H3GIgngon"

	for i := 0; i < 5; i++ {
		go func(j int) {
			ch := g.DoChan(key, func() (interface{}, error) {
				ret, err := find(ctx, key)
				return ret, err
			})

			select {
			case <-ctx.Done():
				// Timeout after 1s
				fmt.Println(ctx.Err())
			case ret = <-ch: // Received result from channel
				fmt.Printf(" val: %v, shared: %v\n", ret.Val, ret.Shared)
			}
		}(i)
	}
	fmt.Println("22222222222222222222222222")

	time.Sleep(time.Hour)
}

func find(ctx context.Context, query string) (data, error) {
	time.Sleep(time.Minute)
	return data(fmt.Sprintf("result for %q", query)), nil
}

2. References

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub