sh를 통으로 atomic하게 교체
This commit is contained in:
@ -257,8 +257,7 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
|
|||||||
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(&newService))
|
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(&newService))
|
||||||
}
|
}
|
||||||
|
|
||||||
serptr := atomic.LoadPointer(&mg.service().serviceSerialized)
|
w.Write(mg.service().divisionsSerialized)
|
||||||
w.Write(*(*[]byte)(serptr))
|
|
||||||
} else if r.Method == "POST" {
|
} else if r.Method == "POST" {
|
||||||
body, _ := io.ReadAll(r.Body)
|
body, _ := io.ReadAll(r.Body)
|
||||||
var service serviceDescription
|
var service serviceDescription
|
||||||
@ -293,8 +292,7 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
|
|||||||
func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) error {
|
func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) error {
|
||||||
mg := caller.mg
|
mg := caller.mg
|
||||||
if r.Method == "GET" {
|
if r.Method == "GET" {
|
||||||
serptr := atomic.LoadPointer(&mg.service().divisionsSerialized)
|
w.Write(mg.service().divisionsSerialized)
|
||||||
w.Write(*(*[]byte)(serptr))
|
|
||||||
} else if r.Method == "POST" {
|
} else if r.Method == "POST" {
|
||||||
var divs map[string]*Division
|
var divs map[string]*Division
|
||||||
dec := json.NewDecoder(r.Body)
|
dec := json.NewDecoder(r.Body)
|
||||||
|
|||||||
@ -501,7 +501,7 @@ func (mg *Maingate) RegisterHandlers(ctx context.Context, serveMux *http.ServeMu
|
|||||||
|
|
||||||
logger.Println("Service is registered :", mg.service().ServiceCode)
|
logger.Println("Service is registered :", mg.service().ServiceCode)
|
||||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, mg.service().ServiceCode, "/"), func(w http.ResponseWriter, r *http.Request) {
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, mg.service().ServiceCode, "/"), func(w http.ResponseWriter, r *http.Request) {
|
||||||
mg.service().ServeHTTP(w, r)
|
mg.service().serveHTTP(w, r)
|
||||||
})
|
})
|
||||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "api/"), mg.api)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "api/"), mg.api)
|
||||||
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "query/"), mg.query)
|
serveMux.HandleFunc(gocommon.MakeHttpHandlerPattern(prefix, "query/"), mg.query)
|
||||||
|
|||||||
@ -131,13 +131,13 @@ type serviceDescription struct {
|
|||||||
ServiceDescriptionSummary `bson:",inline" json:",inline"`
|
ServiceDescriptionSummary `bson:",inline" json:",inline"`
|
||||||
Divisions map[string]*Division `bson:"divisions" json:"divisions"`
|
Divisions map[string]*Division `bson:"divisions" json:"divisions"`
|
||||||
ServerApiTokens []primitive.ObjectID `bson:"api_tokens" json:"api_tokens"`
|
ServerApiTokens []primitive.ObjectID `bson:"api_tokens" json:"api_tokens"`
|
||||||
Admins []string `bson:"admins" json:"admins"`
|
MaximumNumLinkAccount int64
|
||||||
|
VersionSplits map[string]string `bson:"version_splits" json:"version_splits"`
|
||||||
|
|
||||||
auths *gocommon.AuthCollection
|
auths *gocommon.AuthCollection
|
||||||
wl *whitelist
|
wl *whitelist
|
||||||
mongoClient gocommon.MongoClient
|
mongoClient gocommon.MongoClient
|
||||||
sessionTTL time.Duration
|
sessionTTL time.Duration
|
||||||
MaximumNumLinkAccount int64
|
|
||||||
|
|
||||||
serviceCodeBytes []byte
|
serviceCodeBytes []byte
|
||||||
getUserBrowserInfo func(r *http.Request) (string, error)
|
getUserBrowserInfo func(r *http.Request) (string, error)
|
||||||
@ -145,11 +145,11 @@ type serviceDescription struct {
|
|||||||
updateUserinfo func(info usertokeninfo) (bool, string, string)
|
updateUserinfo func(info usertokeninfo) (bool, string, string)
|
||||||
getProviderInfo func(platform string, uid string) (string, string, error)
|
getProviderInfo func(platform string, uid string) (string, string, error)
|
||||||
|
|
||||||
admins unsafe.Pointer
|
divisionsForUsersSerialized []byte
|
||||||
divisionsForUsersSerialized unsafe.Pointer
|
divisionsSerialized []byte
|
||||||
divisionsSerialized unsafe.Pointer
|
serviceSerialized []byte
|
||||||
serviceSerialized unsafe.Pointer
|
serviceSummarySerialized []byte
|
||||||
serviceSummarySerialized unsafe.Pointer
|
divisionsSplits map[string][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sh *serviceDescription) isValidToken(apiToken primitive.ObjectID) bool {
|
func (sh *serviceDescription) isValidToken(apiToken primitive.ObjectID) bool {
|
||||||
@ -211,7 +211,9 @@ func (sh *serviceDescription) prepare(mg *Maingate) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
divsForUsers := make(map[string]*DivisionForUser)
|
divsForUsers := make(map[string]*DivisionForUser)
|
||||||
|
var namesOnly []string
|
||||||
for dn, div := range divs {
|
for dn, div := range divs {
|
||||||
|
namesOnly = append(namesOnly, dn)
|
||||||
if div.State == DivisionState_Closed {
|
if div.State == DivisionState_Closed {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -249,13 +251,25 @@ func (sh *serviceDescription) prepare(mg *Maingate) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
divmarshaled, _ := json.Marshal(divs)
|
sh.divisionsSerialized, _ = json.Marshal(divs)
|
||||||
devstr := string(divmarshaled)
|
sh.divisionsForUsersSerialized, _ = json.Marshal(divsForUsers)
|
||||||
sh.divisionsSerialized = unsafe.Pointer(&devstr)
|
|
||||||
|
|
||||||
divmarshaled2, _ := json.Marshal(divsForUsers)
|
if len(sh.VersionSplits) == 0 {
|
||||||
devstr2 := string(divmarshaled2)
|
sh.VersionSplits = map[string]string{
|
||||||
sh.divisionsForUsersSerialized = unsafe.Pointer(&devstr2)
|
"": strings.Join(namesOnly, ","),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sh.divisionsSplits = make(map[string][]byte)
|
||||||
|
for ver, divnamesT := range sh.VersionSplits {
|
||||||
|
divnames := strings.Split(divnamesT, ",")
|
||||||
|
split := make(map[string]*DivisionForUser)
|
||||||
|
for _, divname := range divnames {
|
||||||
|
split[divname] = divsForUsers[divname]
|
||||||
|
}
|
||||||
|
splitMarshaled, _ := json.Marshal(split)
|
||||||
|
sh.divisionsSplits[ver] = splitMarshaled
|
||||||
|
}
|
||||||
|
|
||||||
sh.MaximumNumLinkAccount = mg.maingateConfig.MaximumNumLinkAccount
|
sh.MaximumNumLinkAccount = mg.maingateConfig.MaximumNumLinkAccount
|
||||||
sh.mongoClient = mg.mongoClient
|
sh.mongoClient = mg.mongoClient
|
||||||
@ -267,19 +281,11 @@ func (sh *serviceDescription) prepare(mg *Maingate) error {
|
|||||||
sh.updateUserinfo = mg.updateUserinfo
|
sh.updateUserinfo = mg.updateUserinfo
|
||||||
sh.getProviderInfo = mg.getProviderInfo
|
sh.getProviderInfo = mg.getProviderInfo
|
||||||
|
|
||||||
if sh.Admins == nil {
|
|
||||||
sh.Admins = []string{}
|
|
||||||
}
|
|
||||||
sh.admins = unsafe.Pointer(&sh.Admins)
|
|
||||||
|
|
||||||
sh.wl = &mg.wl
|
sh.wl = &mg.wl
|
||||||
bt, _ := json.Marshal(sh)
|
sh.divisionsSerialized, _ = json.Marshal(sh)
|
||||||
atomic.StorePointer(&sh.serviceSerialized, unsafe.Pointer(&bt))
|
sh.serviceSummarySerialized, _ = json.Marshal(sh.ServiceDescriptionSummary)
|
||||||
|
|
||||||
btsum, _ := json.Marshal(sh.ServiceDescriptionSummary)
|
logger.Println("service is ready :", sh.ServiceCode, string(sh.divisionsSerialized))
|
||||||
atomic.StorePointer(&sh.serviceSummarySerialized, unsafe.Pointer(&btsum))
|
|
||||||
|
|
||||||
logger.Println("service is ready :", sh.ServiceCode, sh.Admins, string(divmarshaled))
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -743,7 +749,20 @@ func (sh *serviceDescription) authorize(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sh *serviceDescription) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (sh *serviceDescription) findVersionSplit(version string) []byte {
|
||||||
|
if len(version) > 0 {
|
||||||
|
for k, v := range sh.divisionsSplits {
|
||||||
|
if strings.HasPrefix(version, k) {
|
||||||
|
if version == k || version[len(k)] == '.' {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sh.divisionsSplits[""]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sh *serviceDescription) serveHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
defer func() {
|
defer func() {
|
||||||
s := recover()
|
s := recover()
|
||||||
if s != nil {
|
if s != nil {
|
||||||
@ -784,9 +803,8 @@ func (sh *serviceDescription) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
divstrptr := atomic.LoadPointer(&sh.divisionsForUsersSerialized)
|
version := queryvals.Get("version")
|
||||||
divstr := *(*string)(divstrptr)
|
w.Write(sh.findVersionSplit(version))
|
||||||
w.Write([]byte(divstr))
|
|
||||||
} else if strings.HasSuffix(r.URL.Path, "/addr") {
|
} else if strings.HasSuffix(r.URL.Path, "/addr") {
|
||||||
queryvals := r.URL.Query()
|
queryvals := r.URL.Query()
|
||||||
sk := queryvals.Get("sk")
|
sk := queryvals.Get("sk")
|
||||||
|
|||||||
@ -285,11 +285,9 @@ func (mg *Maingate) watchServiceCollection(parentctx context.Context, serveMux *
|
|||||||
logger.Error("service cannot be prepared :", data.Service, err)
|
logger.Error("service cannot be prepared :", data.Service, err)
|
||||||
} else {
|
} else {
|
||||||
// 내가 임시로 가지고 있던 서비스일 수 있다.
|
// 내가 임시로 가지고 있던 서비스일 수 있다.
|
||||||
already := mg.service().Id == data.Service.Id
|
if mg.service().Id == data.Service.Id {
|
||||||
logger.Println("service is on the board! :", data.Service)
|
logger.Println("service is on the board! :", data.Service)
|
||||||
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(data.Service))
|
atomic.StorePointer(&mg.serviceptr, unsafe.Pointer(data.Service))
|
||||||
if !already {
|
|
||||||
serveMux.Handle(gocommon.MakeHttpHandlerPattern(prefix, data.Service.ServiceCode, "/"), mg.service())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user