hyperbahn/client.go
func NewClient(ch *tchannel.Channel, config Configuration, opts *ClientOptions) (*Client, error) {
	client := &Client{tchan: ch, quit: make(chan struct{})}
	if opts != nil {
		client.opts = *opts
	}
	if client.opts.Timeout == 0 {
		client.opts.Timeout = 3 * time.Second
	}
	if client.opts.TimeoutPerAttempt == 0 {
		client.opts.TimeoutPerAttempt = time.Second
	}
	if client.opts.Handler == nil {
		client.opts.Handler = nullHandler{}
	}
	if client.opts.TimeSleep == nil {
		client.opts.TimeSleep = time.Sleep
	}

	if err := parseConfig(&config); err != nil {
		return nil, err
	}

	// Add the given initial nodes as peers.
	for _, node := range config.InitialNodes {
		addPeer(ch, node)
	}

	client.jsonClient = tjson.NewClient(ch, hyperbahnServiceName, nil)
	thriftClient := tthrift.NewClient(ch, hyperbahnServiceName, nil)
	client.hyperbahnClient = htypes.NewTChanHyperbahnClient(thriftClient)

	return client, nil
}
func NewClient(ch *tchannel.Channel, config Configuration, opts *ClientOptions) (*Client, error) {
	client := &Client{tchan: ch, quit: make(chan struct{})}
	if opts != nil {
		client.opts = *opts
	}
	if client.opts.Timeout == 0 {
		client.opts.Timeout = 3 * time.Second
	}
	if client.opts.TimeoutPerAttempt == 0 {
		client.opts.TimeoutPerAttempt = time.Second
	}
	if client.opts.Handler == nil {
		client.opts.Handler = nullHandler{}
	}
	if client.opts.TimeSleep == nil {
		client.opts.TimeSleep = time.Sleep
	}

	if err := parseConfig(&config); err != nil {
		return nil, err
	}

	// Add the given initial nodes as peers.
	for _, node := range config.InitialNodes {
		addPeer(ch, node)
	}

	client.jsonClient = tjson.NewClient(ch, hyperbahnServiceName, nil)
	thriftClient := tthrift.NewClient(ch, hyperbahnServiceName, nil)
	client.hyperbahnClient = htypes.NewTChanHyperbahnClient(thriftClient)

	return client, nil
}
// NewClient creates a new Hyperbahn client using the given channel.
// config is the environment-specific configuration for Hyperbahn such as the list of initial nodes.
// opts are optional, and are used to customize the client.