code: func ProcessBatchedData(socketRead io.ReadCloser, socketWrite io.Writer,
  	makeProcessBatch func() (func([]byte) []byte, func([]byte, []byte)),
  	batchSize int, workItemSize int) {
  	readChan := make(chan []byte, 2)
  	writeChan := make(chan []byte, 2)
  	go readBatch(readChan, socketRead, batchSize, workItemSize)
  	go writeBatch(writeChan, socketWrite)
  	processBatch, prefetchBatch := makeProcessBatch()
  	for buf := range readChan {
  		res := processBatch(buf)
  		writeChan <- res
  		prefetchBatch(buf, res)
  	}
  	close(writeChan)
  }
docs: // this function takes data from socketRead and calls processBatch on a batch of it at a time
  // then the resulting bytes are written to wocketWrite as fast as possible