func (i *Introduction) Exhausted() bool {
	return len(i.Result.Unqueried) == 0 && !i.ReachedTarget()
}
Exhausted returns whether all of the possible peers have been queried.
package introduce
import (
	"sync"
	"time"
	"github.com/drausin/libri/libri/common/ecid"
	"github.com/drausin/libri/libri/librarian/api"
	"github.com/drausin/libri/libri/librarian/client"
	"github.com/drausin/libri/libri/librarian/server/peer"
)
var (
	DefaultTargetNumIntroductions = uint(128)
	DefaultMinNumIntroductions = uint(3)
	DefaultNumPeersPerRequest = uint(16)
	DefaultNMaxErrors = uint(3)
	DefaultConcurrency = uint(3)
	DefaultQueryTimeout = 5 * time.Second
)
type Parameters struct {
	TargetNumIntroductions uint
	MinNumIntroductions uint
	NumPeersPerRequest uint
	NMaxErrors uint
	Concurrency uint
	Timeout time.Duration
}
func NewDefaultParameters() *Parameters {
	return &Parameters{
		TargetNumIntroductions: DefaultTargetNumIntroductions,
		MinNumIntroductions:    DefaultMinNumIntroductions,
		NumPeersPerRequest:     DefaultNumPeersPerRequest,
		NMaxErrors:             DefaultNMaxErrors,
		Concurrency:            DefaultConcurrency,
		Timeout:                DefaultQueryTimeout,
	}
}
type Result struct {
	Unqueried map[string]peer.Peer
	Responded map[string]peer.Peer
	NErrors uint
	FatalErr error
}
func NewInitialResult() *Result {
	return &Result{
		Unqueried: make(map[string]peer.Peer),
		Responded: make(map[string]peer.Peer),
	}
}
type Introduction struct {
	NewRequest func() *api.IntroduceRequest
	Result *Result
	Params *Parameters
	mu sync.Mutex
}
func NewIntroduction(
	selfID, orgID ecid.ID, apiSelf *api.PeerAddress, params *Parameters,
) *Introduction {
	return &Introduction{
		NewRequest: func() *api.IntroduceRequest {
			return client.NewIntroduceRequest(
				selfID,
				orgID,
				apiSelf,
				params.NumPeersPerRequest,
			)
		},
		Result: NewInitialResult(),
		Params: params,
	}
}
func (i *Introduction) wrapLock(operation func()) {
	i.mu.Lock()
	defer i.mu.Unlock()
	operation()
}
func (i *Introduction) ReachedTarget() bool {
	return uint(len(i.Result.Responded)) >= i.Params.TargetNumIntroductions
}
func (i *Introduction) ReachedMin() bool {
	return uint(len(i.Result.Responded)) >= i.Params.MinNumIntroductions
}