code: func (s *Subscription) NextMsg(timeout time.Duration) (*Msg, error) {
  	if s == nil {
  		return nil, ErrBadSubscription
  	}
  
  	s.mu.Lock()
  	err := s.validateNextMsgState()
  	if err != nil {
  		s.mu.Unlock()
  		return nil, err
  	}
  
  	// snapshot
  	mch := s.mch
  	s.mu.Unlock()
  
  	var ok bool
  	var msg *Msg
  
  	// If something is available right away, let's optimize that case.
  	select {
  	case msg, ok = <-mch:
  		if !ok {
  			return nil, ErrConnectionClosed
  		}
  		if err := s.processNextMsgDelivered(msg); err != nil {
  			return nil, err
  		} else {
  			return msg, nil
  		}
  	default:
  	}
  
  	// If we are here a message was not immediately available, so lets loop
  	// with a timeout.
  
  	t := globalTimerPool.Get(timeout)
  	defer globalTimerPool.Put(t)
  
  	select {
  	case msg, ok = <-mch:
  		if !ok {
  			return nil, ErrConnectionClosed
  		}
  		if err := s.processNextMsgDelivered(msg); err != nil {
  			return nil, err
  		}
  	case <-t.C:
  		return nil, ErrTimeout
  	}
  
  	return msg, nil
  }
docs: // NextMsg will return the next message available to a synchronous subscriber
  // or block until one is available. A timeout can be used to return when no
  // message has been delivered.