sh를 통으로 atomic하게 교체

This commit is contained in:
2023-08-16 21:44:19 +09:00
parent c7f073c779
commit 42b4ade782
4 changed files with 56 additions and 42 deletions

View File

@ -131,13 +131,13 @@ type serviceDescription struct {
ServiceDescriptionSummary `bson:",inline" json:",inline"`
Divisions map[string]*Division `bson:"divisions" json:"divisions"`
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
wl *whitelist
mongoClient gocommon.MongoClient
sessionTTL time.Duration
MaximumNumLinkAccount int64
auths *gocommon.AuthCollection
wl *whitelist
mongoClient gocommon.MongoClient
sessionTTL time.Duration
serviceCodeBytes []byte
getUserBrowserInfo func(r *http.Request) (string, error)
@ -145,11 +145,11 @@ type serviceDescription struct {
updateUserinfo func(info usertokeninfo) (bool, string, string)
getProviderInfo func(platform string, uid string) (string, string, error)
admins unsafe.Pointer
divisionsForUsersSerialized unsafe.Pointer
divisionsSerialized unsafe.Pointer
serviceSerialized unsafe.Pointer
serviceSummarySerialized unsafe.Pointer
divisionsForUsersSerialized []byte
divisionsSerialized []byte
serviceSerialized []byte
serviceSummarySerialized []byte
divisionsSplits map[string][]byte
}
func (sh *serviceDescription) isValidToken(apiToken primitive.ObjectID) bool {
@ -211,7 +211,9 @@ func (sh *serviceDescription) prepare(mg *Maingate) error {
}
divsForUsers := make(map[string]*DivisionForUser)
var namesOnly []string
for dn, div := range divs {
namesOnly = append(namesOnly, dn)
if div.State == DivisionState_Closed {
continue
}
@ -249,13 +251,25 @@ func (sh *serviceDescription) prepare(mg *Maingate) error {
}
}
divmarshaled, _ := json.Marshal(divs)
devstr := string(divmarshaled)
sh.divisionsSerialized = unsafe.Pointer(&devstr)
sh.divisionsSerialized, _ = json.Marshal(divs)
sh.divisionsForUsersSerialized, _ = json.Marshal(divsForUsers)
divmarshaled2, _ := json.Marshal(divsForUsers)
devstr2 := string(divmarshaled2)
sh.divisionsForUsersSerialized = unsafe.Pointer(&devstr2)
if len(sh.VersionSplits) == 0 {
sh.VersionSplits = map[string]string{
"": 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.mongoClient = mg.mongoClient
@ -267,19 +281,11 @@ func (sh *serviceDescription) prepare(mg *Maingate) error {
sh.updateUserinfo = mg.updateUserinfo
sh.getProviderInfo = mg.getProviderInfo
if sh.Admins == nil {
sh.Admins = []string{}
}
sh.admins = unsafe.Pointer(&sh.Admins)
sh.wl = &mg.wl
bt, _ := json.Marshal(sh)
atomic.StorePointer(&sh.serviceSerialized, unsafe.Pointer(&bt))
sh.divisionsSerialized, _ = json.Marshal(sh)
sh.serviceSummarySerialized, _ = json.Marshal(sh.ServiceDescriptionSummary)
btsum, _ := json.Marshal(sh.ServiceDescriptionSummary)
atomic.StorePointer(&sh.serviceSummarySerialized, unsafe.Pointer(&btsum))
logger.Println("service is ready :", sh.ServiceCode, sh.Admins, string(divmarshaled))
logger.Println("service is ready :", sh.ServiceCode, string(sh.divisionsSerialized))
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() {
s := recover()
if s != nil {
@ -784,9 +803,8 @@ func (sh *serviceDescription) ServeHTTP(w http.ResponseWriter, r *http.Request)
return
}
divstrptr := atomic.LoadPointer(&sh.divisionsForUsersSerialized)
divstr := *(*string)(divstrptr)
w.Write([]byte(divstr))
version := queryvals.Get("version")
w.Write(sh.findVersionSplit(version))
} else if strings.HasSuffix(r.URL.Path, "/addr") {
queryvals := r.URL.Query()
sk := queryvals.Get("sk")