func Scatter(inputLen int, work func(int, int, *sync.RWMutex) (interface{}, error)) ([]*ScatterResult, error) {
	if inputLen <= 0 {
		return nil, errors.New("no data with which to work")
	}
	extentSize := calculateExtentSize(inputLen)
	workers := inputLen / extentSize
	if inputLen%extentSize != 0 {
		workers++
	}
	resultCh := make(chan *ScatterResult, workers)
	defer close(resultCh)
	errorCh := make(chan error, workers)
	defer close(errorCh)
	mutex := new(sync.RWMutex)
	for worker := 0; worker < workers; worker++ {
		offset := worker * extentSize
		entries := extentSize
		if offset+entries > inputLen {
			entries = inputLen - offset
		}
		go func(offset int, entries int) {
			extent, err := work(offset, entries, mutex)
			if err != nil {
				errorCh <- err
			} else {
				resultCh <- &ScatterResult{
					Offset: offset,
					Extent: extent,
				}
			}
		}(offset, entries)
	}
	results := make([]*ScatterResult, workers)
	var err error
	for i := 0; i < workers; i++ {
		select {
		case result := <-resultCh:
			results[i] = result
		case err = <-errorCh:
		}
	}
	return results, err
}
Scatter scatters a computation across multiple goroutines, returning a set of per-worker results
package util
import (
	"errors"
	"runtime"
	"sync"
)
type ScatterResult struct {
	Offset int
	Extent interface{}
}