func (m Multi) Run(ctx context.Context, inputs []MultiInput) <-chan MultiOutput {
	parallelism := m.Parallelism
	if parallelism <= 0 {
		const defaultParallelism = 3
		parallelism = defaultParallelism
	}
	inputch := make(chan MultiInput)
	outputch := make(chan MultiOutput)
	go m.source(inputs, inputch)
	for i := 0; i < parallelism; i++ {
		go m.do(ctx, inputch, outputch)
	}
	return outputch
}
Run performs several urlgetters in parallel. This function returns a channel
where each result is posted. This function will always perform all the requested
measurements: if the ctx is canceled or its deadline expires, then you will see
a bunch of failed measurements. Since all measurements are always performed,
you know you're done when you've read len(inputs) results in output.
package urlgetter
import (
	"context"
	"fmt"
	"time"
	"github.com/ooni/probe-engine/model"
)
type MultiInput struct {
	Config Config
	Target string
}
type MultiOutput struct {
	Input MultiInput
	Err error
	TestKeys TestKeys
}
type MultiGetter func(ctx context.Context, g Getter) (TestKeys, error)
func DefaultMultiGetter(ctx context.Context, g Getter) (TestKeys, error) {
	return g.Get(ctx)
}
type Multi struct {
	Begin time.Time
	Getter MultiGetter
	Parallelism int
	Session model.ExperimentSession
}