180 lines
4.3 KiB
Go
180 lines
4.3 KiB
Go
|
package service
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"encoding/json"
|
||
|
"time"
|
||
|
|
||
|
"go-common/app/interface/main/kvo/model"
|
||
|
"go-common/app/interface/main/kvo/model/module"
|
||
|
|
||
|
"go-common/library/database/sql"
|
||
|
"go-common/library/ecode"
|
||
|
"go-common/library/log"
|
||
|
)
|
||
|
|
||
|
// Document get document
|
||
|
func (s *Service) Document(c context.Context, mid int64, moduleKey string, timestamp int64, checkSum int64) (setting *module.Setting, err error) {
|
||
|
var (
|
||
|
uc *model.UserConf
|
||
|
rm json.RawMessage
|
||
|
moduleKeyID int
|
||
|
)
|
||
|
if moduleKeyID = module.VerifyModuleKey(moduleKey); moduleKeyID == 0 {
|
||
|
err = ecode.RequestErr
|
||
|
return
|
||
|
}
|
||
|
uc, err = s.userConf(c, mid, moduleKeyID)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
if uc.CheckSum == 0 || uc.Timestamp == 0 {
|
||
|
err = ecode.NotModified
|
||
|
return
|
||
|
}
|
||
|
// 数据没有变动
|
||
|
if uc.CheckSum == checkSum && uc.Timestamp == timestamp {
|
||
|
err = ecode.NotModified
|
||
|
return
|
||
|
}
|
||
|
rm, err = s.document(c, uc.CheckSum)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
setting = &module.Setting{
|
||
|
Timestamp: uc.Timestamp,
|
||
|
CheckSum: uc.CheckSum,
|
||
|
Data: rm,
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Service) userConf(c context.Context, mid int64, moduleKeyID int) (uc *model.UserConf, err error) {
|
||
|
uc, err = s.da.UserConfCache(c, mid, moduleKeyID)
|
||
|
if err != nil {
|
||
|
log.Error("service.userConf.UserConfCache(%v,%v) err:%v", mid, moduleKeyID, err)
|
||
|
}
|
||
|
if uc != nil {
|
||
|
s.sp.Incr("user_conf_cached")
|
||
|
return
|
||
|
}
|
||
|
uc, err = s.da.UserConf(c, mid, moduleKeyID)
|
||
|
if err != nil {
|
||
|
log.Error("service.userConf(%v,%v) err:%v", mid, moduleKeyID, err)
|
||
|
return
|
||
|
}
|
||
|
if uc == nil {
|
||
|
uc = &model.UserConf{
|
||
|
Mid: mid,
|
||
|
ModuleKey: moduleKeyID,
|
||
|
}
|
||
|
s.sp.Incr("default_user_conf")
|
||
|
}
|
||
|
s.sp.Incr("user_conf_missed")
|
||
|
s.updateUcCache(mid, moduleKeyID)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (s *Service) document(c context.Context, checkSum int64) (rm json.RawMessage, err error) {
|
||
|
var (
|
||
|
doc *model.Document
|
||
|
)
|
||
|
rm, err = s.da.DocumentCache(c, checkSum)
|
||
|
if err != nil {
|
||
|
log.Error("service.document.DocumentCache(%v) err:%v", checkSum, err)
|
||
|
}
|
||
|
if rm != nil {
|
||
|
s.sp.Incr("document_cached")
|
||
|
return
|
||
|
}
|
||
|
doc, err = s.da.Document(c, checkSum)
|
||
|
if err != nil {
|
||
|
log.Error("service.document(%v) err:%v", checkSum, err)
|
||
|
return
|
||
|
}
|
||
|
if doc == nil {
|
||
|
err = ecode.NothingFound
|
||
|
s.sp.Incr("user_conf_document_error")
|
||
|
return
|
||
|
}
|
||
|
s.sp.Incr("document_missed")
|
||
|
rm = json.RawMessage(doc.Doc)
|
||
|
s.da.SetDocumentCache(c, checkSum, rm)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// AddDocument add a user document
|
||
|
func (s *Service) AddDocument(c context.Context, mid int64, moduleKey string, data string, timestamp int64, oldSum int64, now time.Time) (resp *model.UserConf, err error) {
|
||
|
var (
|
||
|
uc *model.UserConf
|
||
|
doc *model.Document
|
||
|
rm json.RawMessage
|
||
|
checkSum int64
|
||
|
tx *sql.Tx
|
||
|
moduleKeyID int
|
||
|
)
|
||
|
if moduleKeyID = module.VerifyModuleKey(moduleKey); moduleKeyID == 0 {
|
||
|
return nil, ecode.RequestErr
|
||
|
}
|
||
|
if rm, checkSum, err = module.Result(moduleKeyID, data); err != nil {
|
||
|
log.Error("service.GetModule(%v,%s) err:%v", moduleKey, data, err)
|
||
|
return nil, ecode.RequestErr
|
||
|
}
|
||
|
if len(rm) > s.docLimit {
|
||
|
err = ecode.KvoDataOverLimit
|
||
|
return
|
||
|
}
|
||
|
if uc, err = s.da.UserConf(c, mid, moduleKeyID); err != nil {
|
||
|
log.Error("service.AddDocument.UserConf(%v,%v) err:%v", mid, moduleKeyID, err)
|
||
|
return
|
||
|
}
|
||
|
s.updateUcCache(mid, moduleKeyID)
|
||
|
if uc != nil {
|
||
|
if uc.Timestamp != timestamp {
|
||
|
err = ecode.KvoTimestampErr
|
||
|
log.Error("service.AddDocument.CompareTimeStamp(%v,%v,%v) err:%v", mid, uc.Timestamp, timestamp, err)
|
||
|
return
|
||
|
}
|
||
|
if uc.CheckSum != oldSum {
|
||
|
err = ecode.KvoCheckSumErr
|
||
|
return
|
||
|
}
|
||
|
if uc.CheckSum == checkSum {
|
||
|
err = ecode.NotModified
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
// trans
|
||
|
tx, err = s.da.BeginTx(c)
|
||
|
if err != nil {
|
||
|
log.Error("s.da.BeginTx err:%v", err)
|
||
|
return
|
||
|
}
|
||
|
if err = s.da.TxUpUserConf(c, tx, mid, moduleKeyID, checkSum, now); err != nil {
|
||
|
log.Error("s.da.TxUpUserConf(%v,%v,%v) error(%v)", mid, moduleKeyID, checkSum, err)
|
||
|
tx.Rollback()
|
||
|
return
|
||
|
}
|
||
|
doc, err = s.da.Document(c, checkSum)
|
||
|
if err != nil {
|
||
|
tx.Rollback()
|
||
|
return
|
||
|
}
|
||
|
if doc == nil {
|
||
|
if err = s.da.TxUpDocuement(c, tx, checkSum, string(rm), now); err != nil {
|
||
|
log.Error("s.da.TxUpDocuement(%v,%v,%v) error(%v)", mid, moduleKeyID, checkSum, err)
|
||
|
tx.Rollback()
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if err = tx.Commit(); err != nil {
|
||
|
log.Error("tx.Commit(), error(%v)", err)
|
||
|
}
|
||
|
resp = &model.UserConf{
|
||
|
CheckSum: checkSum,
|
||
|
Timestamp: now.Unix(),
|
||
|
}
|
||
|
s.updateUcCache(mid, moduleKeyID)
|
||
|
return
|
||
|
}
|