code: func (s *Subscription) NextMsgWithContext(ctx context.Context) (*Msg, error) {
  	if ctx == nil {
  		return nil, ErrInvalidContext
  	}
  	if s == nil {
  		return nil, ErrBadSubscription
  	}
  	if ctx.Err() != nil {
  		return nil, ctx.Err()
  	}
  
  	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:
  	}
  
  	select {
  	case msg, ok = <-mch:
  		if !ok {
  			return nil, ErrConnectionClosed
  		}
  		if err := s.processNextMsgDelivered(msg); err != nil {
  			return nil, err
  		}
  	case <-ctx.Done():
  		return nil, ctx.Err()
  	}
  
  	return msg, nil
  }
docs: // NextMsgWithContext takes a context and returns the next message
  // available to a synchronous subscriber, blocking until it is delivered
  // or context gets canceled.