github.com/abolfazlbeh/zhycan@v0.0.0-20230819144214-24cf38237387/internal/grpc/manager.go (about) 1 package grpc 2 3 import ( 4 "encoding/json" 5 "github.com/abolfazlbeh/zhycan/internal/config" 6 "github.com/abolfazlbeh/zhycan/internal/logger" 7 "log" 8 "sync" 9 "time" 10 ) 11 12 // MARK: Variables 13 14 var ( 15 gRPCMaintenanceType = logger.NewLogType("PROTOBUF_MANAGER_MAINTENANCE") 16 ) 17 18 // Mark: manager 19 20 // manager struct 21 type manager struct { 22 name string 23 lock sync.Mutex 24 servers map[string]*ServerWrapper 25 isStarted bool 26 } 27 28 // MARK: Module variables 29 var managerInstance *manager = nil 30 var once sync.Once 31 32 // Module init function 33 func init() { 34 log.Println("gRPC Manager Package Initialized...") 35 } 36 37 // Manager Constructor - It initializes the db configuration params 38 func (m *manager) init() { 39 m.name = "protobuf" 40 41 m.lock.Lock() 42 defer m.lock.Unlock() 43 44 servers, err := config.GetManager().Get(m.name, "servers") 45 if err != nil { 46 return 47 } 48 49 serverArray := make([]string, len(servers.([]interface{}))) 50 for i, v := range servers.([]interface{}) { 51 serverArray[i] = v.(string) 52 } 53 54 m.servers = make(map[string]*ServerWrapper) 55 56 for _, item := range serverArray { 57 conf, err := config.GetManager().Get(m.name, item) 58 if err != nil { 59 continue 60 } 61 62 jsonBody, err2 := json.Marshal(conf) 63 if err2 != nil { 64 continue 65 } 66 67 var obj ServerConfig 68 err = json.Unmarshal(jsonBody, &obj) 69 if err == nil { 70 s, err := NewServer(m.name+"."+item, obj) 71 if err == nil { 72 m.servers[item] = s 73 } 74 } 75 } 76 77 // Config config server to reload 78 wrapper, err := config.GetManager().GetConfigWrapper(m.name) 79 if err == nil { 80 wrapper.RegisterChangeCallback(func() interface{} { 81 return nil 82 }) 83 } 84 } 85 86 // MARK: Public Functions 87 88 // GetManager - This function returns singleton instance of gRPC Manager 89 func GetManager() *manager { 90 // once used for prevent race condition and manage critical section. 91 once.Do(func() { 92 managerInstance = &manager{} 93 managerInstance.init() 94 }) 95 return managerInstance 96 } 97 98 // StartServers - This function starts the gRPC servers 99 func (m *manager) StartServers() { 100 l, _ := logger.GetManager().GetLogger() 101 102 m.lock.Lock() 103 defer m.lock.Unlock() 104 105 ch := make(chan error, len(m.servers)) 106 107 for _, item := range m.servers { 108 if item.IsInitialized() { 109 err := item.Start(&ch) 110 if err != nil { 111 if l != nil { 112 l.Log(logger.NewLogObject(logger.ERROR, "protobuf.manager.StartServer", gRPCMaintenanceType, time.Now(), "Cannot start server ...", err)) 113 } 114 } 115 } 116 } 117 118 go func(ch1 *chan error) { 119 select { 120 case err := <-*ch1: 121 if l != nil { 122 l.Log(logger.NewLogObject(logger.ERROR, "protobuf.manager.StartServer", gRPCMaintenanceType, time.Now(), "Cannot start server ...", err)) 123 } 124 } 125 }(&ch) 126 127 if l != nil { 128 l.Log(logger.NewLogObject(logger.INFO, "protobuf.manager.StartServer", gRPCMaintenanceType, time.Now(), "Engine Started ...", nil)) 129 } 130 131 m.isStarted = true 132 } 133 134 // StopServers - This function stops gRPC server 135 func (m *manager) StopServers() { 136 m.lock.Lock() 137 defer m.lock.Unlock() 138 139 for _, item := range m.servers { 140 item.Stop() 141 } 142 m.isStarted = false 143 } 144 145 // GetServerByName - get server instance by its name 146 func (m *manager) GetServerByName(name string) (*ServerWrapper, error) { 147 if v, ok := m.servers[name]; ok { 148 return v, nil 149 } 150 151 return nil, NewGrpcServerNotExistError(name) 152 }