code: func (d *Death) closeInMass(closable ...io.Closer) (err error) {
  
  	count := len(closable)
  	sentToClose := make(map[int]closer)
  	//call close async
  	doneClosers := make(chan closer, count)
  	for i, c := range closable {
  		name, pkgPath := getPkgPath(c)
  		closer := closer{Index: i, C: c, Name: name, PKGPath: pkgPath}
  		go d.closeObjects(closer, doneClosers)
  		sentToClose[i] = closer
  	}
  
  	// wait on channel for notifications.
  	timer := time.NewTimer(d.timeout)
  	failedClosers := []closer{}
  	for {
  		select {
  		case <-timer.C:
  			s := "failed to close: "
  			pkgs := []string{}
  			for _, c := range sentToClose {
  				pkgs = append(pkgs, fmt.Sprintf("%s/%s", c.PKGPath, c.Name))
  				d.log.Error("Failed to close: ", c.PKGPath, "/", c.Name)
  			}
  			return fmt.Errorf("%s", fmt.Sprintf("%s %s", s, strings.Join(pkgs, ", ")))
  		case closer := <-doneClosers:
  			delete(sentToClose, closer.Index)
  			count--
  			if closer.Err != nil {
  				failedClosers = append(failedClosers, closer)
  			}
  
  			d.log.Debug(count, " object(s) left")
  			if count != 0 || len(sentToClose) != 0 {
  				continue
  			}
  
  			if len(failedClosers) != 0 {
  				errString := generateErrString(failedClosers)
  				return fmt.Errorf("errors from closers: %s", errString)
  			}
  
  			return nil
  		}
  	}
  }
docs: // closeInMass Close all the objects at once and wait for them to finish with a channel. Return an
  // error if you fail to close all the objects