Performance optimizations and memory management

Added some benchmarks to secure channel and played around with improving its performance, also started using a sync.Pool for message buffers.
I think this method should be wait-able.

```Go
func FetchGraph(ctx context.Context, root *Node, serv DAGService) chan struct{} {

  var wg sync.WaitGroup
  done := make(chan struct{})

  for _, l := range root.Links {
    wg.Add(1)
    go func(lnk *Link) {
      // signal child is done on the way out.
      defer wg.Done()

      select {
      case <-ctx.Done():
        return
      }

      nd, err := lnk.GetNode(serv)
      if err != nil {
        log.Error(err)
        return
      }

      // wait on child to be done.
      <-FetchGraph(ctx, nd, serv)
    }(l)
  }
  
  go func() {
    wg.Wait()
    done<- struct{} // signal we're done.
  }()
  
  return done
}
```