Я внедряю клиент GRPC, используя кобру.Различные служебные вызовы находятся за подкомандами.
Чтобы избежать дублирования кода, я сохраняю одно соединение и одного клиента в viper
синглтоне.Но я не уверен, что это правильный способ сделать это.
Прямо сейчас, в cmd/root.go::initConfig()
, я создаю соединение и клиент и сохраняю их.
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
c := pb.NewCommandClient(conn)
viper.SetDefault("Client", c)
viper.SetDefault("Connection", conn)
Соединение закрытов rootCmd.PersistentPostRun()
, определенном в том же файле root.go
.
PersistentPostRun: func(cmd *cobra.Command, args []string) {
conn := viper.Get("Connection").(*grpc.ClientConn)
conn.Close()
},
А клиент извлекается из viper
и используется в файлах подкоманд 'Run
, например,
c := viper.Get("Client").(pb.CommandClient)
c.DoSomething() // call the service functions on c
Эта реализация работает, но я не уверен, что это хорошая практика.В частности
- Разве плохо создавать соединение в одной функции и закрывать его в другой функции?
- Имеет ли смысл сохранять клиента в
viper
или лучшесоздать новый в каждой функции подкоманды Run
?
Весь исходный код находится в этом репо