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  }