func (self redisCacheProvider) Pop(group string) (uint64, error) { if len(group) == 0 { errorMsg := fmt.Sprint("The group name is INVALID!") base.Logger().Errorln(errorMsg) return 0, errors.New(errorMsg) } rwSign := getRWSign(group) rwSign.RSet() defer rwSign.RUnset() conn := redisPool.Get() defer conn.Close() value, err := conn.Do("RPOP", group) if err != nil { errorMsg := fmt.Sprintf("Redis Error <RPOP %s>: %s\n ", group, err.Error()) base.Logger().Error(errorMsg) return 0, errors.New(errorMsg) } if value == nil { errorMsg := fmt.Sprintf("Empty List! (group=%s)", group) return 0, &base.EmptyListError{errorMsg} } baValue := value.([]uint8) number, err := strconv.ParseUint(string(baValue), 10, 64) if err != nil { errorMsg := fmt.Sprintf("Converting Error (value=%s): %s\n ", value, err.Error()) base.Logger().Error(errorMsg) return 0, errors.New(errorMsg) } return number, nil }
func main() { flag.Parse() http.HandleFunc("/id", doForId) base.Logger().Infof("Starting id center http server (port=%d)...\n", serverPort) err := http.ListenAndServe(":"+fmt.Sprintf("%d", serverPort), nil) if err != nil { base.Logger().Fatalln("Listen and serve error: ", err) } else { base.Logger().Infoln("The id center http server is started.") } }
func pushResponse(bufrw *bufio.ReadWriter, content interface{}, group string, op string) { literals := fmt.Sprintf("%v", content) _, err := bufrw.Write([]byte(literals)) if err == nil { err = bufrw.Flush() } if err != nil { base.Logger().Errorf("Pushing response error (content=%v, group=%s, op=%s): %s\n", literals, group, op, err) } else { base.Logger().Errorf("The response '%v' has been pushed. (group=%s, op=%s)\n", literals, group, op) } }
func (self *IdCenterManager) Clear(group string) (bool, error) { defer func() { if err := recover(); err != nil { debug.PrintStack() errorMsg := fmt.Sprintf("Occur FATAL error when clear (group=%v): %s", group, err) base.Logger().Fatalln(errorMsg) } }() storageProvider := self.getStorageProvider() spResult, spErr := storageProvider.Clear(group) cacheProvider := self.getCacheProvider() cpResult, cpErr := cacheProvider.Clear(group) if spErr != nil || cpErr != nil { var errorMsgBuffer bytes.Buffer errorMsgBuffer.WriteString("Clear Failing:") if spErr != nil { errorMsgBuffer.WriteString(fmt.Sprintf("%s: %s; ", reflect.TypeOf(storageProvider).Name(), spErr)) } if cpErr != nil { errorMsgBuffer.WriteString(fmt.Sprintf("%s: %s; ", reflect.TypeOf(cacheProvider).Name(), cpErr)) } errorMsgBuffer.WriteString("\n") return false, errors.New(errorMsgBuffer.String()) } return (spResult && cpResult), nil }
func RegisterProvider(provider base.Provider) error { defer func() { if err := recover(); err != nil { debug.PrintStack() errorMsg := fmt.Sprintf("Occur FATAL error when register provider (provider=%v): %s", provider, err) base.Logger().Fatalln(errorMsg) } }() if provider == nil { panicMsg := "IdCenter: The provider is nil!\n" base.Logger().Fatal(panicMsg) panic(panicMsg) } name := provider.Name() if len(name) == 0 { panicMsg := "IdCenter: The name of provider is nil!\n" base.Logger().Fatal(panicMsg) panic(panicMsg) } switch t := interface{}(provider).(type) { case base.CacheProvider: if _, contains := cacheProviderMap[name]; contains { errorMsg := fmt.Sprintf("IdCenter: Repetitive cache provider name '%s'!\n", name) base.Logger().Error(errorMsg) return errors.New(errorMsg) } cp, ok := interface{}(provider).(base.CacheProvider) if !ok { errorMsg := fmt.Sprintf("IdCenter: Incorrect cache provider type! (name '%s')\n", name) base.Logger().Error(errorMsg) return errors.New(errorMsg) } cacheProviderMap[name] = cp case base.StorageProvider: if _, contains := storageProviderMap[name]; contains { errorMsg := fmt.Sprintf("IdCenter: Repetitive storage provider name '%s'!\n", name) base.Logger().Error(errorMsg) return errors.New(errorMsg) } sp, ok := interface{}(provider).(base.StorageProvider) if !ok { errorMsg := fmt.Sprintf("IdCenter: Incorrect cache provider type! (name '%s')\n", name) base.Logger().Error(errorMsg) return errors.New(errorMsg) } storageProviderMap[name] = sp default: panicMsg := fmt.Sprintf("IdCenter: Unexpected Provider type '%v'! (name=%s)\n", t, name) base.Logger().Fatal(panicMsg) panic(panicMsg) } return nil }
func doForId(w http.ResponseWriter, r *http.Request) { hj, ok := w.(http.Hijacker) var errorMsg string if !ok { errorMsg = "The Web Server does not support Hijacking! " http.Error(w, errorMsg, http.StatusInternalServerError) base.Logger().Errorf(errorMsg) return } conn, bufrw, err := hj.Hijack() if err != nil { errorMsg = "Internal error!" http.Error(w, errorMsg, http.StatusInternalServerError) base.Logger().Errorf(errorMsg+" Hijacking Error: %s\n", err) return } defer conn.Close() r.ParseForm() group := r.FormValue("group") op := r.FormValue("op") base.Logger().Infof("Receive a request for id (group=%s, op=%s))...\n", group, op) var respContent interface{} if op == "clear" { result, err := idCenterManager.Clear(group) if err != nil { errorMsg = fmt.Sprintf("Clear id group error: %s", err) base.Logger().Errorln(errorMsg) } respContent = interface{}(result) } else { currentId, err := idCenterManager.GetId(group) if err != nil { errorMsg = fmt.Sprintf("Get id error: %s", err) base.Logger().Errorln(errorMsg) } respContent = interface{}(currentId) } if len(errorMsg) > 0 { respContent = interface{}("Internal error!") } pushResponse(bufrw, respContent, group, op) }
func (self redisCacheProvider) Clear(group string) (bool, error) { if len(group) == 0 { errorMsg := fmt.Sprint("The group name is INVALID!") base.Logger().Errorln(errorMsg) return false, errors.New(errorMsg) } rwSign := getRWSign(group) rwSign.RSet() defer rwSign.RUnset() conn := redisPool.Get() defer conn.Close() effectedKeys, err := redis.Int(conn.Do("DEL", group)) if err != nil { errorMsg := fmt.Sprintf("Redis Error <DEL %s>: %s\n ", group, err.Error()) base.Logger().Error(errorMsg) return false, errors.New(errorMsg) } base.Logger().Infof("Redis Cache Provider: The group '%s' is cleared. (affectedKeys=%v)", group, (effectedKeys > 0)) return true, nil }
func (self redisCacheProvider) BuildList(group string, begin uint64, end uint64) (bool, error) { if len(group) == 0 { errorMsg := fmt.Sprint("The group name is INVALID!") base.Logger().Errorln(errorMsg) return false, errors.New(errorMsg) } rwSign := getRWSign(group) rwSign.Set() defer rwSign.Unset() if (begin <= 0) || (end <= 0) || (begin >= end) { errorMsg := fmt.Sprintf("Invalid Parameter(s)! (begin=%d, end=%d)\n", begin, end) base.Logger().Error(errorMsg) return false, errors.New(errorMsg) } conn := redisPool.Get() defer conn.Close() exists, err := redis.Bool(conn.Do("EXISTS", group)) if err != nil { errorMsg := fmt.Sprintf("Redis Error <EXISTS %s>: %s\n ", group, err.Error()) base.Logger().Errorf(errorMsg) return false, errors.New(errorMsg) } if exists { effectedKeys, err := redis.Int(conn.Do("DEL", group)) if err != nil { errorMsg := fmt.Sprintf("Redis Error <DEL %s>: %s\n ", group, err.Error()) base.Logger().Error(errorMsg) return false, errors.New(errorMsg) } if effectedKeys < 1 { warningMsg := fmt.Sprintf("Redis warning <DEL %s>: seemingly failed.\n ", group) base.Logger().Warn(warningMsg) } } for i := begin; i < end; i++ { length, err := redis.Int(conn.Do("LPUSH", group, i)) if err != nil { errorMsg := fmt.Sprintf("Redis Error <LPUSH %s %d> (total_length=%d): %s\n ", group, i, length, err.Error()) base.Logger().Error(errorMsg) return false, errors.New(errorMsg) } } base.Logger().Infof("The list of group '%s' is builded. (begin=%d, end=%d)\n", group, begin, end) return true, nil }
func initializeForCacheProvider(parameter RedisParameter) error { redisServerAddr := fmt.Sprintf("%v:%v", parameter.Ip, parameter.Port) base.Logger().Infof("Initialize redis cache provider (parameter=%v)...", parameter) redisPool = &redis.Pool{ MaxIdle: int(parameter.PoolSize), IdleTimeout: 240 * time.Second, Dial: func() (redis.Conn, error) { c, err := redis.Dial("tcp", redisServerAddr) if err != nil { return nil, err } if len(parameter.Password) > 0 { if _, err := c.Do("AUTH", parameter.Password); err != nil { c.Close() return nil, err } } return c, err }, } rwSignMap = make(map[string]*go_lib.RWSign) iRedisCacheProvider = &redisCacheProvider{parameter.Name} return nil }
func UnregisterProvider(provider base.Provider) { defer func() { if err := recover(); err != nil { debug.PrintStack() errorMsg := fmt.Sprintf("Occur FATAL error when unregister provider (provider=%v): %s", provider, err) base.Logger().Fatalln(errorMsg) } }() if provider == nil { panicMsg := "IdCenter: The provider is nil!\n" base.Logger().Fatal(panicMsg) panic(panicMsg) } name := provider.Name() if len(name) == 0 { panicMsg := "IdCenter: The name of provider is nil!\n" base.Logger().Fatal(panicMsg) panic(panicMsg) } switch t := interface{}(provider).(type) { case base.CacheProvider: _, contains := cacheProviderMap[name] if contains { delete(cacheProviderMap, name) } else { base.Logger().Warnf("IdCenter: The cache Provider named '%s' is NOTEXISTENT!\n", name) } case base.StorageProvider: _, contains := storageProviderMap[name] if contains { delete(storageProviderMap, name) } else { base.Logger().Warnf("IdCenter: The storage Provider named '%s' is NOTEXISTENT!\n", name) } default: panicMsg := fmt.Sprintf("IdCenter: Unexpected Provider type '%v'! (name=%s)\n", t, name) base.Logger().Fatal(panicMsg) panic(panicMsg) } return }
func (self *IdCenterManager) GetId(group string) (uint64, error) { defer func() { if err := recover(); err != nil { debug.PrintStack() errorMsg := fmt.Sprintf("Occur FATAL error when get id (group=%v): %s", group, err) base.Logger().Fatalln(errorMsg) } }() cacheProvider := self.getCacheProvider() storageProvider := self.getStorageProvider() id, err := cacheProvider.Pop(group) if err != nil { switch err.(type) { case *base.EmptyListError: warningMsg := fmt.Sprintf("Warning: The list of group '%s' is empty.", group) base.Logger().Warn(warningMsg) default: errorMsg := fmt.Sprintf("Occur error when pop id for group '%s': %s\n", group, err.Error()) base.Logger().Error(errorMsg) return 0, err } } if id > 0 { return id, nil } base.Logger().Infof("Prepare check & build id list for group '%s'...\n", group) groupInfo, err := storageProvider.Get(group) if err != nil { errorMsg := fmt.Sprintf("Occur error when get group (name='%s') info : %s\n", group, err.Error()) base.Logger().Error(errorMsg) return 0, err } if groupInfo == nil { currentStart := self.Start if currentStart <= 0 { currentStart = DEFAULT_START } currentStep := self.Step if currentStep <= 0 { currentStep = DEFAULT_STEP } ok, err := storageProvider.BuildInfo(group, currentStart, currentStep) if err != nil { errorMsg := fmt.Sprintf("Occur error when initialize group '%s': %s", group, err.Error()) base.Logger().Errorln(errorMsg) return 0, err } if !ok { warnMsg := fmt.Sprintf("Building group info is FAILING. Maybe the group already exists. (group=%v)", group) base.Logger().Warnln(warnMsg) } } idRange, err := storageProvider.Propel(group) if err != nil { errorMsg := fmt.Sprintf("Occur error when propel id for group '%s': %s\n", group, err.Error()) base.Logger().Error(errorMsg) return 0, err } currentBegin := idRange.Begin currentEnd := idRange.End ok, err := cacheProvider.BuildList(group, currentBegin, currentEnd) if err != nil { errorMsg := fmt.Sprintf("Occur error when build id list for group '%s': %s\n", group, err.Error()) base.Logger().Error(errorMsg) return 0, err } if !ok { warnMsg := fmt.Sprintf("Building id list is FAILING. (group=%v)", group) base.Logger().Warnln(warnMsg) } id, err = cacheProvider.Pop(group) if err != nil { switch err.(type) { case *base.EmptyListError: warningMsg := fmt.Sprintf("Warning: The list of group '%s' is empty.", group) base.Logger().Warn(warningMsg) default: errorMsg := fmt.Sprintf("Occur error when pop id for group '%s': %s\n", group, err.Error()) base.Logger().Error(errorMsg) return 0, err } } return id, nil }
func init() { flag.IntVar(&serverPort, "port", 9092, "the server (http listen) port") iConfig = go_lib.Config{Path: base.CONFIG_FILE_NAME} err := iConfig.ReadConfig(false) if err != nil { errorMsg := fmt.Sprintf("Config Loading error: %s", err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } configRedisPort := iConfig.Dict["redis_server_port"] redisPort, err := strconv.Atoi(configRedisPort) if err != nil { errorMsg := fmt.Sprintf("The redis server port '%v' is INVALID! Error: %s", configRedisPort, err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } configRedisPoolSize := iConfig.Dict["redis_server_pool_size"] redisPoolSize, err := strconv.Atoi(configRedisPoolSize) if err != nil { errorMsg := fmt.Sprintf("The redis server pool size '%v' is INVALID! Error: %s", redisPoolSize, err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } cacheParameter := provider.RedisParameter{ Name: "Redis Cache Provider", Ip: iConfig.Dict["redis_server_ip"], Port: redisPort, Password: iConfig.Dict["redis_server_password"], PoolSize: uint16(redisPoolSize), } rcp := manager.NewRedisCacheProvider(cacheParameter) err = manager.RegisterProvider(interface{}(rcp).(base.Provider)) if err != nil { errorMsg := fmt.Sprintf("Redis Cache provider register error: %s", err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } configMysqlPort := iConfig.Dict["mysql_server_port"] mysqlPort, err := strconv.Atoi(configMysqlPort) if err != nil { errorMsg := fmt.Sprintf("The mysql server port '%v' is INVALID! Error: %s", configMysqlPort, err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } configMysqlPoolSize := iConfig.Dict["mysql_server_pool_size"] mysqlPoolSize, err := strconv.Atoi(configMysqlPoolSize) if err != nil { errorMsg := fmt.Sprintf("The mysql server pool size '%v' is INVALID! Error: %s", configMysqlPoolSize, err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } storageParameter := provider.MysqlParameter{ Name: "Mysql Storage Provider", Ip: iConfig.Dict["redis_server_ip"], Port: mysqlPort, DbName: iConfig.Dict["mysql_server_db_name"], User: iConfig.Dict["mysql_server_user"], Password: iConfig.Dict["mysql_server_password"], PoolSize: uint16(mysqlPoolSize), } msp := manager.NewMysqlStorageProvider(storageParameter) err = manager.RegisterProvider(interface{}(msp).(base.Provider)) if err != nil { errorMsg := fmt.Sprintf("MySQL Storage provider register error: %s", err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } configIdStart := iConfig.Dict["id_start"] idStart, err := strconv.Atoi(configIdStart) if err != nil { errorMsg := fmt.Sprintf("The start number of id '%v' is INVALID! Error: %s", configIdStart, err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } configIdStep := iConfig.Dict["id_step"] idStep, err := strconv.Atoi(configIdStep) if err != nil { errorMsg := fmt.Sprintf("The step number of id '%v' is INVALID! Error: %s", configIdStep, err) base.Logger().Fatalf(errorMsg) panic(errors.New(errorMsg)) } idCenterManager = manager.IdCenterManager{ CacheProviderName: rcp.Name(), StorageProviderName: msp.Name(), Start: uint64(idStart), Step: uint32(idStep), } }