code: func (s *scheduler) build(ctx context.Context, edge Edge) (CachedResult, error) {
  	s.mu.Lock()
  	e := s.ef.getEdge(edge)
  	if e == nil {
  		s.mu.Unlock()
  		return nil, errors.Errorf("invalid request %v for build", edge)
  	}
  
  	wait := make(chan struct{})
  
  	var p *pipe.Pipe
  	p = s.newPipe(e, nil, pipe.Request{Payload: &edgeRequest{desiredState: edgeStatusComplete}})
  	p.OnSendCompletion = func() {
  		p.Receiver.Receive()
  		if p.Receiver.Status().Completed {
  			close(wait)
  		}
  	}
  	s.mu.Unlock()
  
  	ctx, cancel := context.WithCancel(ctx)
  	defer cancel()
  
  	go func() {
  		<-ctx.Done()
  		p.Receiver.Cancel()
  	}()
  
  	<-wait
  
  	if err := p.Receiver.Status().Err; err != nil {
  		return nil, err
  	}
  	return p.Receiver.Status().Value.(*edgeState).result.Clone(), nil
  }
docs: // build evaluates edge into a result