go-common/app/interface/main/kvo/service/document.go
2019-04-22 18:49:16 +08:00

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
}