Create & Init Project...
This commit is contained in:
60
app/interface/main/tv/dao/history/BUILD
Normal file
60
app/interface/main/tv/dao/history/BUILD
Normal file
@ -0,0 +1,60 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"cursor_test.go",
|
||||
"dao_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/interface/main/history/model:go_default_library",
|
||||
"//app/interface/main/tv/conf:go_default_library",
|
||||
"//app/interface/main/tv/model/history:go_default_library",
|
||||
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cursor.go",
|
||||
"dao.go",
|
||||
],
|
||||
importpath = "go-common/app/interface/main/tv/dao/history",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/interface/main/history/model:go_default_library",
|
||||
"//app/interface/main/history/rpc/client:go_default_library",
|
||||
"//app/interface/main/tv/conf:go_default_library",
|
||||
"//app/interface/main/tv/model/history:go_default_library",
|
||||
"//library/cache/memcache:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/net/metadata:go_default_library",
|
||||
"//library/stat/prom:go_default_library",
|
||||
"//vendor/github.com/pkg/errors:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
87
app/interface/main/tv/dao/history/cursor.go
Normal file
87
app/interface/main/tv/dao/history/cursor.go
Normal file
@ -0,0 +1,87 @@
|
||||
package history
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
hismodel "go-common/app/interface/main/history/model"
|
||||
"go-common/app/interface/main/tv/model/history"
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/log"
|
||||
"go-common/library/net/metadata"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func keyHis(mid int64) string {
|
||||
return fmt.Sprintf("tv_his_%d", mid)
|
||||
}
|
||||
|
||||
// Cursor get history rpc data
|
||||
func (d *Dao) Cursor(c context.Context, mid, max int64, ps int, tp int8, businesses []string) (res []*hismodel.Resource, err error) {
|
||||
ip := metadata.String(c, metadata.RemoteIP)
|
||||
arg := &hismodel.ArgCursor{Mid: mid, Max: max, Ps: ps, RealIP: ip, TP: tp, ViewAt: max, Businesses: businesses}
|
||||
if res, err = d.hisRPC.HistoryCursor(c, arg); err != nil {
|
||||
err = errors.Wrapf(err, "d.historyRPC.HistoryCursor(%+v)", arg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// HisCache get history cms cache.
|
||||
func (d *Dao) HisCache(c context.Context, mid int64) (s *history.HisMC, err error) {
|
||||
var (
|
||||
key = keyHis(mid)
|
||||
conn = d.mc.Get(c)
|
||||
item *memcache.Item
|
||||
)
|
||||
defer conn.Close()
|
||||
if item, err = conn.Get(key); err != nil {
|
||||
if err == memcache.ErrNotFound {
|
||||
err = nil
|
||||
missedCount.Add("tv-his", 1)
|
||||
} else {
|
||||
log.Error("conn.Get(%s) error(%v)", key, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = conn.Scan(item, &s); err != nil {
|
||||
log.Error("conn.Get(%s) error(%v)", key, err)
|
||||
}
|
||||
cachedCount.Add("tv-his", 1)
|
||||
return
|
||||
}
|
||||
|
||||
// SaveHisCache save the member's history into cache
|
||||
func (d *Dao) SaveHisCache(ctx context.Context, filtered []*history.HisRes) {
|
||||
var hismc = &history.HisMC{}
|
||||
if len(filtered) == 0 {
|
||||
hismc.LastViewAt = time.Now().Unix()
|
||||
} else {
|
||||
firstItem := filtered[0]
|
||||
hismc.LastViewAt = firstItem.Unix
|
||||
hismc.MID = firstItem.Mid
|
||||
}
|
||||
hismc.Res = filtered
|
||||
d.addHisCache(ctx, hismc)
|
||||
}
|
||||
|
||||
// addHisCache adds the history into cache
|
||||
func (d *Dao) addHisCache(ctx context.Context, his *history.HisMC) {
|
||||
d.addCache(func() {
|
||||
d.setHisCache(ctx, his)
|
||||
})
|
||||
}
|
||||
|
||||
// setHisCache add his cache
|
||||
func (d *Dao) setHisCache(c context.Context, his *history.HisMC) (err error) {
|
||||
conn := d.mc.Get(c)
|
||||
defer conn.Close()
|
||||
item := &memcache.Item{Key: keyHis(his.MID), Object: his, Flags: memcache.FlagJSON, Expiration: d.expireHis}
|
||||
if err = conn.Set(item); err != nil {
|
||||
log.Error("conn.Store(%s) error(%v)", keyHis(his.MID), err)
|
||||
}
|
||||
log.Info("set HisMC Mid %d", his.MID)
|
||||
return
|
||||
}
|
111
app/interface/main/tv/dao/history/cursor_test.go
Normal file
111
app/interface/main/tv/dao/history/cursor_test.go
Normal file
@ -0,0 +1,111 @@
|
||||
package history
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
hmdl "go-common/app/interface/main/history/model"
|
||||
"go-common/app/interface/main/tv/model/history"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
testMid = int64(320773689)
|
||||
testAid = int64(10110670)
|
||||
testHisMC = &history.HisMC{
|
||||
MID: testMid,
|
||||
Res: []*history.HisRes{
|
||||
{
|
||||
Mid: testMid,
|
||||
Oid: testAid,
|
||||
},
|
||||
},
|
||||
LastViewAt: time.Now().Unix(),
|
||||
}
|
||||
)
|
||||
|
||||
func TestDao_Cursor(t *testing.T) {
|
||||
convey.Convey("TestDao_Cursor", t, WithDao(func(d *Dao) {
|
||||
var (
|
||||
mcDataHis = &hmdl.ArgHistory{
|
||||
Mid: testMid,
|
||||
Realtime: time.Now().Unix(),
|
||||
History: &hmdl.History{
|
||||
Mid: testMid,
|
||||
Aid: testAid,
|
||||
Business: "archive",
|
||||
},
|
||||
}
|
||||
)
|
||||
res, err := d.Cursor(ctx, testMid, 0, 100, 0, []string{"pgc", "archive"})
|
||||
if len(res) == 0 {
|
||||
if errAdd := d.hisRPC.Add(ctx, mcDataHis); errAdd != nil {
|
||||
fmt.Println(errAdd)
|
||||
return
|
||||
}
|
||||
res, err = d.Cursor(ctx, testMid, 0, 100, 0, []string{"pgc", "archive"})
|
||||
}
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
convey.So(len(res), convey.ShouldBeGreaterThan, 0)
|
||||
data, _ := json.Marshal(res)
|
||||
fmt.Println(string(data))
|
||||
}))
|
||||
}
|
||||
|
||||
func TestHistorykeyHis(t *testing.T) {
|
||||
var (
|
||||
mid = int64(320773689)
|
||||
)
|
||||
convey.Convey("keyHis", t, func(c convey.C) {
|
||||
p1 := keyHis(mid)
|
||||
c.Convey("Then p1 should not be nil.", func(c convey.C) {
|
||||
c.So(p1, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestHistorySaveHisCache(t *testing.T) {
|
||||
var (
|
||||
filtered = []*history.HisRes{
|
||||
{
|
||||
Mid: testMid,
|
||||
Oid: testAid,
|
||||
},
|
||||
}
|
||||
)
|
||||
convey.Convey("SaveHisCache", t, func(c convey.C) {
|
||||
d.SaveHisCache(ctx, filtered)
|
||||
c.Convey("No return values", func(c convey.C) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestHistoryaddHisCache(t *testing.T) {
|
||||
convey.Convey("addHisCache", t, func(c convey.C) {
|
||||
d.addHisCache(ctx, testHisMC)
|
||||
c.Convey("No return values", func(c convey.C) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestHistorysetHisCache(t *testing.T) {
|
||||
convey.Convey("setHisCache", t, func(c convey.C) {
|
||||
err := d.setHisCache(ctx, testHisMC)
|
||||
c.Convey("Then err should be nil.", func(c convey.C) {
|
||||
c.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestHistoryHisCache(t *testing.T) {
|
||||
convey.Convey("HisCache", t, func(c convey.C) {
|
||||
s, err := d.HisCache(ctx, testMid)
|
||||
c.Convey("Then err should be nil.s should not be nil.", func(c convey.C) {
|
||||
c.So(err, convey.ShouldBeNil)
|
||||
c.So(s, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
57
app/interface/main/tv/dao/history/dao.go
Normal file
57
app/interface/main/tv/dao/history/dao.go
Normal file
@ -0,0 +1,57 @@
|
||||
package history
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
hisrpc "go-common/app/interface/main/history/rpc/client"
|
||||
"go-common/app/interface/main/tv/conf"
|
||||
"go-common/library/cache/memcache"
|
||||
"go-common/library/log"
|
||||
"go-common/library/stat/prom"
|
||||
)
|
||||
|
||||
// Dao is account dao.
|
||||
type Dao struct {
|
||||
// rpc
|
||||
hisRPC *hisrpc.Service
|
||||
mc *memcache.Pool
|
||||
mCh chan func()
|
||||
expireHis int32
|
||||
}
|
||||
|
||||
// New account dao.
|
||||
func New(c *conf.Config) (d *Dao) {
|
||||
d = &Dao{
|
||||
hisRPC: hisrpc.New(c.HisRPC),
|
||||
mc: memcache.NewPool(c.Memcache.Config),
|
||||
mCh: make(chan func(), 10240),
|
||||
expireHis: int32(time.Duration(c.Memcache.HisExpire) / time.Second),
|
||||
}
|
||||
for i := 0; i < runtime.NumCPU()*2; i++ {
|
||||
go d.cacheproc()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
cachedCount = prom.CacheHit
|
||||
missedCount = prom.CacheMiss
|
||||
)
|
||||
|
||||
// addCache add archive to mc or redis
|
||||
func (d *Dao) addCache(f func()) {
|
||||
select {
|
||||
case d.mCh <- f:
|
||||
default:
|
||||
log.Warn("cacheproc chan full")
|
||||
}
|
||||
}
|
||||
|
||||
// cacheproc write memcache and stat redis use goroutine
|
||||
func (d *Dao) cacheproc() {
|
||||
for {
|
||||
f := <-d.mCh
|
||||
f()
|
||||
}
|
||||
}
|
44
app/interface/main/tv/dao/history/dao_test.go
Normal file
44
app/interface/main/tv/dao/history/dao_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package history
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"go-common/app/interface/main/tv/conf"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
d *Dao
|
||||
ctx = context.TODO()
|
||||
)
|
||||
|
||||
func init() {
|
||||
//dir, _ := filepath.Abs("../../cmd/tv-interface.toml")
|
||||
//flag.Set("conf", dir)
|
||||
if os.Getenv("DEPLOY_ENV") != "" {
|
||||
flag.Set("app_id", "main.web-svr.tv-interface")
|
||||
flag.Set("conf_token", "07c1826c1f39df02a1411cdd6f455879")
|
||||
flag.Set("tree_id", "15326")
|
||||
flag.Set("conf_version", "docker-1")
|
||||
flag.Set("deploy_env", "uat")
|
||||
flag.Set("conf_host", "config.bilibili.co")
|
||||
flag.Set("conf_path", "/tmp")
|
||||
flag.Set("region", "sh")
|
||||
flag.Set("zone", "sh001")
|
||||
}
|
||||
flag.Parse()
|
||||
if err := conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
d = New(conf.Conf)
|
||||
}
|
||||
|
||||
func WithDao(f func(d *Dao)) func() {
|
||||
return func() {
|
||||
Reset(func() {})
|
||||
f(d)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user