code: func (c *Client) SemaphoreOpts(opts *SemaphoreOptions) (*Semaphore, error) {
  	if opts.Prefix == "" {
  		return nil, fmt.Errorf("missing prefix")
  	}
  	if opts.Limit <= 0 {
  		return nil, fmt.Errorf("semaphore limit must be positive")
  	}
  	if opts.SessionName == "" {
  		opts.SessionName = DefaultSemaphoreSessionName
  	}
  	if opts.SessionTTL == "" {
  		opts.SessionTTL = DefaultSemaphoreSessionTTL
  	} else {
  		if _, err := time.ParseDuration(opts.SessionTTL); err != nil {
  			return nil, fmt.Errorf("invalid SessionTTL: %v", err)
  		}
  	}
  	if opts.MonitorRetryTime == 0 {
  		opts.MonitorRetryTime = DefaultMonitorRetryTime
  	}
  	if opts.SemaphoreWaitTime == 0 {
  		opts.SemaphoreWaitTime = DefaultSemaphoreWaitTime
  	}
  	s := &Semaphore{
  		c:    c,
  		opts: opts,
  	}
  	return s, nil
  }
docs: // SemaphoreOpts is used to create a Semaphore with the given options.
  // The prefix must have write privileges, and the limit must be agreed
  // upon by all contenders. If a Session is not provided, one will be created.