// Copyright 2024 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package http_test import ( "errors" "internal/synctest" ) var errStillRunning = errors.New("async op still running") type asyncResult[T any] struct { donec chan struct{} res T err error } // runAsync runs f in a new goroutine. // It returns an asyncResult which acts as a future. // // Must be called from within a synctest bubble. func runAsync[T any](f func() (T, error)) *asyncResult[T] { r := &asyncResult[T]{ donec: make(chan struct{}), } go func() { defer close(r.donec) r.res, r.err = f() }() synctest.Wait() return r } // done reports whether the function has returned. func (r *asyncResult[T]) done() bool { _, err := r.result() return err != errStillRunning } // result returns the result of the function. // If the function hasn't completed yet, it returns errStillRunning. func (r *asyncResult[T]) result() (T, error) { select { case <-r.donec: return r.res, r.err default: var zero T return zero, errStillRunning } }