Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/job/main/usersuit/cmd:all-srcs",
"//app/job/main/usersuit/conf:all-srcs",
"//app/job/main/usersuit/dao/medal:all-srcs",
"//app/job/main/usersuit/dao/pendant:all-srcs",
"//app/job/main/usersuit/http:all-srcs",
"//app/job/main/usersuit/model:all-srcs",
"//app/job/main/usersuit/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,53 @@
### Version 1.6.0
> 1.增加vip用户的vip挂件装备过期or挂件准备续期逻辑
### Version 1.5.2
> 1.fix bug
### Version 1.5.1
> 1.use account notify
### Version 1.5.0
> 1.delete nameplate
### Version 1.4.9
> 1.change medal owners mc key
### Version 1.4.8
> 1.fix closure
##### Version 1.2.8
> 1.add medal owner update
##### Version 1.2.5
> 1.call rpc
##### Version 1.2.4
> 1.medal cron job
##### Version 1.2.3
> 1.add pagesize conf
##### Version 1.2.2
> 1.update sql
##### Version 1.2.1
> 1.databus config
##### Version 1.2.0
> 1.rebuild medal
> 2.move to app
##### Version 1.1.0
> 1.http to bm
##### Version 1.0.2
> 1.move item to main
##### Version 1.0.1
> 1.删除无效的迁移数据的代码
##### Version 1.0.0
> 1.添加装备挂件过期,通知逻辑

View File

@@ -0,0 +1,11 @@
# Owner
zhaogangtao
wanghuan01
zhoujiahui
# Author
wutao
# Reviewer
linmiao
zhaogangtao

View File

@@ -0,0 +1,17 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- wanghuan01
- wutao
- zhaogangtao
- zhoujiahui
labels:
- job
- job/main/usersuit
- main
options:
no_parent_owners: true
reviewers:
- linmiao
- wutao
- zhaogangtao

View File

@@ -0,0 +1,11 @@
#### usersuit-job
##### 项目简介
> 1.提供挂件装备支持
##### 编译环境
> 请只用golang v1.8.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = [
"convey-test.toml",
"usersuit-job.toml",
],
importpath = "go-common/app/job/main/usersuit/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/job/main/usersuit/conf:go_default_library",
"//app/job/main/usersuit/http:go_default_library",
"//library/log:go_default_library",
"//library/net/trace: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"],
)

View File

@@ -0,0 +1,107 @@
version = "1.0.0"
NotifyURL = "http://account.bilibili.co/api/communicate/purge_cache"
[xlog]
dir = "/data/log/usersuit-job/"
[app]
key = "53e2fa226f5ad348"
secret = "3cf6bd1b0ff671021da5f424fea4b04a"
[bm]
addr = "0.0.0.0:7265"
timeout = "1s"
[mysql]
addr = "172.16.33.205:3309"
dsn = "usersuit:cDXL6vncmCQanx4iMgGogu6gYz33NmA1@tcp(172.16.33.205:3309)/usersuit?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 100
idle = 10
queryTimeout = "2s"
execTimeout = "10s"
tranTimeout = "5s"
[mysql.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[memcache]
name = "usersuit-job"
proto = "tcp"
addr = "172.16.33.54:6379"
idle = 100
active = 100
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
[pendantRedis]
name = "usersuit-service"
proto = "tcp"
addr = "127.0.0.1:6558"
idle = 100
active = 100
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
expire = "720h"
[httpClient]
key = "53e2fa226f5ad348"
secret = "3cf6bd1b0ff671021da5f424fea4b04a"
dial = "500ms"
timeout = "1s"
keepAlive = "60s"
timer = 10
[httpClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[properties]
upInfoURL = "http//127.0.0.1"
medalCron = "0 0 5 ? * ?"
[databus]
[databus.vipBinLog]
key = "4ba46ba31f9a44ef"
secret = "e4c5a7fce28695209e6b4f0af8cf91c5"
group = "BiliVIPBinlog-MainAccount-UsersuitJob-S"
topic = "BiliVIPBinlog-T"
action = "sub"
offset = "old"
buffer = 1024
name = "usersuit-job/databus"
proto = "tcp"
addr = "172.18.33.50:6205"
idle = 1
active = 1
dialTimeout = "1s"
readTimeout = "60s"
writeTimeout = "1s"
idleTimeout = "10s"
[databus.accountNotify]
key = "4ba46ba31f9a44ef"
secret = "e4c5a7fce28695209e6b4f0af8cf91c5"
group = "AccountNotify-MainAccount-P"
topic = "AccountNotify-T"
action = "pub"
offset = "old"
buffer = 128
name = "usersuit-job/databus"
proto = "tcp"
addr = "172.18.33.50:6205"
active = 1
idle = 1
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"

View File

@@ -0,0 +1,45 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"time"
"go-common/app/job/main/usersuit/conf"
"go-common/app/job/main/usersuit/http"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
// init conf,log,trace,stat,perf.
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Xlog)
defer log.Close()
trace.Init(conf.Conf.Tracer)
defer trace.Close()
http.Init(conf.Conf)
// signal handler
log.Info("usersuit-job start")
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("usersuit-job get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
time.Sleep(time.Second * 2)
log.Info("usersuit-job exit")
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,106 @@
version = "1.0.0"
NotifyURL = "http://account.bilibili.co/api/communicate/purge_cache"
[xlog]
dir = "/data/log/usersuit-job/"
[app]
key = "53e2fa226f5ad348"
secret = "3cf6bd1b0ff671021da5f424fea4b04a"
[bm]
addr = "0.0.0.0:7265"
timeout = "1s"
[mysql]
addr = "172.16.33.205:3309"
dsn = "usersuit:cDXL6vncmCQanx4iMgGogu6gYz33NmA1@tcp(172.16.33.205:3309)/usersuit?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 100
idle = 10
queryTimeout = "2s"
execTimeout = "10s"
tranTimeout = "5s"
[mysql.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[pendantRedis]
name = "usersuit-service"
proto = "tcp"
addr = "127.0.0.1:6558"
idle = 100
active = 100
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
[memcache]
name = "usersuit-job"
proto = "tcp"
addr = "172.16.33.54:6379"
idle = 100
active = 100
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"
[httpClient]
key = "53e2fa226f5ad348"
secret = "3cf6bd1b0ff671021da5f424fea4b04a"
dial = "500ms"
timeout = "1s"
keepAlive = "60s"
timer = 10
[httpClient.breaker]
window = "3s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[properties]
upInfoURL = "http//127.0.0.1"
medalCron = "0 0 5 ? * ?"
[databus]
[databus.vipBinLog]
key = "4ba46ba31f9a44ef"
secret = "e4c5a7fce28695209e6b4f0af8cf91c5"
group = "BiliVIPBinlog-MainAccount-UsersuitJob-S"
topic = "BiliVIPBinlog-T"
action = "sub"
offset = "old"
buffer = 1024
name = "usersuit-job/databus"
proto = "tcp"
addr = "172.18.33.50:6205"
idle = 1
active = 1
dialTimeout = "1s"
readTimeout = "60s"
writeTimeout = "1s"
idleTimeout = "10s"
[databus.accountNotify]
key = "4ba46ba31f9a44ef"
secret = "e4c5a7fce28695209e6b4f0af8cf91c5"
group = "AccountNotify-MainAccount-P"
topic = "AccountNotify-T"
action = "pub"
offset = "old"
buffer = 128
name = "usersuit-job/databus"
proto = "tcp"
addr = "172.18.33.50:6205"
active = 1
idle = 1
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "10s"

View File

@@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/job/main/usersuit/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/conf:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/trace:go_default_library",
"//library/queue/databus:go_default_library",
"//vendor/github.com/BurntSushi/toml: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"],
)

View File

@@ -0,0 +1,132 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/rpc"
"go-common/library/net/trace"
"go-common/library/queue/databus"
"github.com/BurntSushi/toml"
)
// Conf global variable.
var (
Conf = &Config{}
client *conf.Client
confPath string
)
// Config struct of conf.
type Config struct {
NotifyURL string
// base
// log
Xlog *log.Config
// tracer
Tracer *trace.Config
// app
App *APP
// bm service
BM *bm.ServerConfig
// db
Mysql *sql.Config
// mecache
Memcache *Memcache
PendantRedis *PendantRedis
// http client
HTTPClient *bm.ClientConfig
PageSize int64
Properties *Properties
SuitRPC *rpc.ClientConfig
Databus *Databus
}
// Databus .
type Databus struct {
AccountNotify *databus.Config
VipBinLog *databus.Config
}
// Memcache define memcache conf.
type Memcache struct {
*memcache.Config
}
// PendantRedis pendant redis
type PendantRedis struct {
*redis.Config
}
// APP appkey and sec
type APP struct {
Key string
Secret string
}
// Properties app config.
type Properties struct {
UpInfoURL string
MedalCron string
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init int config
func Init() error {
if confPath != "" {
return local()
}
return remote()
}

View File

@@ -0,0 +1,56 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dao_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/usersuit/conf:go_default_library",
"//vendor/github.com/go-sql-driver/mysql:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"data.go",
"rpc.go",
],
importpath = "go-common/app/job/main/usersuit/dao/medal",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/job/main/usersuit/conf:go_default_library",
"//app/job/main/usersuit/model:go_default_library",
"//app/service/main/usersuit/model:go_default_library",
"//app/service/main/usersuit/rpc/client:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster: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"],
)

View File

@@ -0,0 +1,45 @@
package medal
import (
"go-common/app/job/main/usersuit/conf"
"go-common/app/service/main/usersuit/rpc/client"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
)
var (
_updateinfo = "/mingpai/api/updateinfo/%s"
)
// Dao struct info of Dao.
type Dao struct {
db *sql.DB
c *conf.Config
client *bm.Client
suitRPC *client.Service2
updateInfo string
// memcache
mc *memcache.Pool
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.Mysql),
client: bm.NewClient(c.HTTPClient),
updateInfo: c.Properties.UpInfoURL + _updateinfo,
suitRPC: client.New(c.SuitRPC),
// memcache
mc: memcache.NewPool(c.Memcache.Config),
}
return
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
}

View File

@@ -0,0 +1,27 @@
package medal
import (
"flag"
"path/filepath"
"testing"
"go-common/app/job/main/usersuit/conf"
_ "github.com/go-sql-driver/mysql"
. "github.com/smartystreets/goconvey/convey"
)
var d *Dao
func init() {
dir, _ := filepath.Abs("../cmd/convey-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
}
func Test_Close(t *testing.T) {
Convey("should return err be nil", t, func() {
d.Close()
})
}

View File

@@ -0,0 +1,26 @@
package medal
import (
"context"
"fmt"
"net/url"
"time"
"go-common/app/job/main/usersuit/model"
"go-common/library/log"
)
// UpInfoData .
func (d *Dao) UpInfoData(c context.Context) (res *model.UpInfo, err error) {
params := url.Values{}
yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
if err = d.client.Get(c, fmt.Sprintf(d.updateInfo, yesterday), "", params, &res); err != nil {
log.Error("GetWearedfansMedal(%s) error(%v)", d.updateInfo+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("GetWearedfansMedal(%s) res(%d)", d.updateInfo+"?"+params.Encode(), res.Code)
}
log.Info("GetWearedfansMedal(%s) res(%+v)", d.updateInfo+"?"+params.Encode(), res)
return
}

View File

@@ -0,0 +1,12 @@
package medal
import (
"context"
"go-common/app/service/main/usersuit/model"
)
// Grant sent a medal to user.
func (d *Dao) Grant(c context.Context, mid, nid int64) (err error) {
err = d.suitRPC.MedalGrant(c, &model.ArgMIDNID{MID: mid, NID: nid})
return
}

View File

@@ -0,0 +1,58 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"mysql_test.go",
"redis_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/usersuit/conf:go_default_library",
"//vendor/github.com/go-sql-driver/mysql:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"mysql.go",
"redis.go",
],
importpath = "go-common/app/job/main/usersuit/dao/pendant",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/job/main/usersuit/conf:go_default_library",
"//app/job/main/usersuit/model:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster: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"],
)

View File

@@ -0,0 +1,54 @@
package pendant
import (
"context"
"go-common/app/job/main/usersuit/conf"
"go-common/library/cache/redis"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
)
// Dao struct info of Dao.
type Dao struct {
db *sql.DB
c *conf.Config
client *bm.Client
// redis
redis *redis.Pool
notifyURL string
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.Mysql),
client: bm.NewClient(c.HTTPClient),
// redis
redis: redis.NewPool(c.PendantRedis.Config),
notifyURL: c.NotifyURL,
}
return
}
// Ping ping health.
func (d *Dao) Ping(c context.Context) (err error) {
return d.pingRedis(c)
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
}
func (d *Dao) pingRedis(c context.Context) (err error) {
conn := d.redis.Get(c)
_, err = conn.Do("SET", "PING", "PONG")
conn.Close()
return
}

View File

@@ -0,0 +1,42 @@
package pendant
import (
"context"
"flag"
"path/filepath"
"testing"
"go-common/app/job/main/usersuit/conf"
_ "github.com/go-sql-driver/mysql"
. "github.com/smartystreets/goconvey/convey"
)
var d *Dao
func init() {
dir, _ := filepath.Abs("../cmd/convey-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
}
func Test_Ping(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.Ping(context.TODO())
So(err, ShouldBeNil)
})
}
func Test_Close(t *testing.T) {
Convey("should return err be nil", t, func() {
d.Close()
})
}
func Test_pingRedis(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.pingRedis(context.TODO())
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,73 @@
package pendant
import (
"context"
"database/sql"
"go-common/app/job/main/usersuit/model"
xsql "go-common/library/database/sql"
)
const (
_upEquipSQL = "UPDATE user_pendant_equip SET pid = 0 AND expires = 0 WHERE mid = ?"
_upEquipExpiresSQL = "UPDATE user_pendant_equip SET expires = ? WHERE mid = ?"
_selEquipSQL = "SELECT mid FROM user_pendant_equip WHERE expires =< ?"
_selEquipMIDSQL = "SELECT mid,pid,expires FROM user_pendant_equip WHERE mid = ?"
_selGidPidSQL = "SELECT gid FROM pendant_group_ref WHERE pid = ?"
)
// UpEquipMID update equip empty by mid
func (d *Dao) UpEquipMID(c context.Context, mid int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _upEquipSQL, mid); err != nil {
return
}
return res.RowsAffected()
}
// UpEquipExpires update equip expires by mid
func (d *Dao) UpEquipExpires(c context.Context, mid, expires int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _upEquipExpiresSQL, expires, mid); err != nil {
return
}
return res.RowsAffected()
}
// PendantEquipMID get user equip pendant by mid.
func (d *Dao) PendantEquipMID(c context.Context, mid int64) (pe *model.PendantEquip, err error) {
row := d.db.QueryRow(c, _selEquipMIDSQL, mid)
pe = new(model.PendantEquip)
if err = row.Scan(&pe.Mid, &pe.Pid, &pe.Expires); err != nil {
return
}
return
}
// ExpireEquipPendant get expire equip pendant
func (d *Dao) ExpireEquipPendant(c context.Context, expires int64) (res []int64, err error) {
var (
row *xsql.Rows
mid int64
)
if row, err = d.db.Query(c, _selEquipSQL, expires); err != nil {
return
}
defer row.Close()
for row.Next() {
if err = row.Scan(&mid); err != nil {
return
}
res = append(res, mid)
}
return
}
// PendantEquipGidPid get gid of its equip pendant by pid.
func (d *Dao) PendantEquipGidPid(c context.Context, pid int64) (gid int64, err error) {
row := d.db.QueryRow(c, _selGidPidSQL, pid)
if err = row.Scan(&gid); err != nil {
return
}
return
}

View File

@@ -0,0 +1,48 @@
package pendant
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestDaoUpEquipMID(t *testing.T) {
Convey("should return err be nil", t, func() {
res, err := d.UpEquipMID(context.Background(), 11)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDaoUpEquipExpires(t *testing.T) {
Convey("should return err be nil", t, func() {
res, err := d.UpEquipExpires(context.TODO(), 11, 123121)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDaoPendantEquipMID(t *testing.T) {
Convey("should return err be nil", t, func() {
res, err := d.PendantEquipMID(context.TODO(), 11)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDaoExpireEquipPendant(t *testing.T) {
Convey("should return err be nil", t, func() {
res, err := d.ExpireEquipPendant(context.TODO(), 11)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDaoPendantEquipGidPid(t *testing.T) {
Convey("should return err be nil", t, func() {
res, err := d.PendantEquipGidPid(context.TODO(), 11)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,37 @@
package pendant
import (
"context"
"strconv"
"go-common/library/log"
)
const (
_pendantPKG = "pkg_" // key of
_pendantEquip = "pe_"
)
// DelPKGCache del package cache
func (d *Dao) DelPKGCache(c context.Context, mid int64) (err error) {
key := _pendantPKG + strconv.FormatInt(mid, 10)
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("DEL", key); err != nil {
log.Error("conn.Send(DEL, %s) error(%v)", key, err)
return
}
return
}
// DelEquipCache set pendant info cache
func (d *Dao) DelEquipCache(c context.Context, mid int64) (err error) {
key := _pendantEquip + strconv.FormatInt(mid, 10)
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("DEL", key); err != nil {
log.Error("conn.Send(DEL, %s) error(%v)", key, err)
return
}
return
}

View File

@@ -0,0 +1,22 @@
package pendant
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func Test_DelPKGCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.DelPKGCache(context.TODO(), 11)
So(err, ShouldBeNil)
})
}
func Test_DelEquipCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.DelEquipCache(context.TODO(), 11)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["http.go"],
importpath = "go-common/app/job/main/usersuit/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/job/main/usersuit/conf:go_default_library",
"//app/job/main/usersuit/service:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster: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"],
)

View File

@@ -0,0 +1,42 @@
package http
import (
"net/http"
"go-common/app/job/main/usersuit/conf"
"go-common/app/job/main/usersuit/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
var svc *service.Service
// Init init
func Init(c *conf.Config) {
initService(c)
// init inner router
engineInner := bm.DefaultServer(c.BM)
innerRouter(engineInner)
if err := engineInner.Start(); err != nil {
log.Error("bm.DefaultServer error(%v)", err)
panic(err)
}
}
// initService init services.
func initService(c *conf.Config) {
svc = service.New(c)
}
// innerRouter init local router api path.
func innerRouter(e *bm.Engine) {
//init api
e.Ping(ping)
}
func ping(c *bm.Context) {
if err := svc.Ping(c); err != nil {
log.Error("usersuit-job ping error")
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}

View File

@@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"medal.go",
"message.go",
"notify.go",
"pendant.go",
"trans.go",
],
importpath = "go-common/app/job/main/usersuit/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//library/time: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"],
)

View File

@@ -0,0 +1,21 @@
package model
const (
// OwnerInstall is_activated=1.
OwnerInstall = 1
// OwnerUninstall is_activated=0.
OwnerUninstall = 0
)
// UpInfo .
type UpInfo struct {
Code int `json:"code"`
Data []*UpInfoGroup `json:"results"`
}
// UpInfoGroup .
type UpInfoGroup struct {
ID int64 `json:"id"`
Desc string `json:"desc"`
Mids []int64 `json:"mids"`
}

View File

@@ -0,0 +1,25 @@
package model
import "encoding/json"
// const .
const (
TimeFormatSec = "2006-01-02 15:04:05"
)
// Message is simple message struct info.
type Message struct {
Action string `json:"action"`
Table string `json:"table"`
New json.RawMessage `json:"new"`
Old json.RawMessage `json:"old"`
}
// VipInfoMessage .
type VipInfoMessage struct {
Mid int64 `json:"mid"`
VipType int8 `json:"vip_type"`
VipPayType int8 `json:"vip_pay_type"`
VipStatus int8 `json:"vip_status"`
VipOverdueTime string `json:"vip_overdue_time"`
}

View File

@@ -0,0 +1,14 @@
package model
//const
const (
AccountNotifyUpdatePendant = "updatePendant"
AccountNotifyUpdateMedal = "updateMedal"
)
// AccountNotify .
type AccountNotify struct {
UID int64 `json:"mid"`
Type string `json:"type"`
Action string `json:"action"`
}

View File

@@ -0,0 +1,8 @@
package model
// PendantEquip .
type PendantEquip struct {
Mid int64
Pid int64
Expires int64
}

View File

@@ -0,0 +1,116 @@
package model
import (
xtime "go-common/library/time"
)
// PendantGroupTrans pendant group pendant
type PendantGroupTrans struct {
Gid int64
GroupName string
Rank string
GroupImage string
IsOnline int32
ModifyTime string
}
// PendantTrans pendant trans
type PendantTrans struct {
Pid int64
Name string
Image string
ImageModel string
DisplayExpire int64
Gid int64
Rank int32
IsOnline int32
ModifyTime string
}
// PendantPriceTrans pendantPrice
type PendantPriceTrans struct {
ID int64
Pid int64
Ecode string
Price int64
Active int32
Ctime string
Mtime string
}
// PTransStatus pendant history
type PTransStatus struct {
ID int64 `json:"id"`
Mid int64 `json:"mid"`
Pid int64 `json:"pid"`
Expire int64 `json:"expire"`
IsActivated int64 `json:"is_activated"`
Mtime string `json:"modify_time"`
}
// PTransHistory pendant trans pendant info
type PTransHistory struct {
ID int64 `json:"id"`
Mid int64 `json:"mid"`
OrderID string `json:"order_id"`
PayID string `json:"pay_id"`
AppID int64 `json:"appid"`
Status int32 `json:"status"`
Pid int64 `json:"pid"`
TimeLength int64 `json:"time_length"`
Cost string `json:"cost"`
BuyTime int64 `json:"buy_time"`
IsCallback int32 `json:"is_callback"`
CallbackTime int64 `json:"callback_time"`
Mtime string `json:"modify_time"`
}
// PGTransHistory pendant grant history
type PGTransHistory struct {
ID int64
Mid int64
OperatorName string
OperatorTime int64
OperatorAction string
OperatorType int32
Mtime string
}
// MedalGroup struct .
type MedalGroup struct {
GID int64
Name string `json:"group_name"`
PID int64 `json:"parent_gid"`
Rank int8 `json:"group_rank"`
IsOnline int8 `json:"is_online"`
IsDel int8
Ctime xtime.Time
Mtime string `json:"modify_time"`
}
// MedalOwner struct db bus trans.
type MedalOwner struct {
ID int64
MID int64
NID int64
IsActivated int8 `json:"is_activated"`
Ctime int64
Mtime string `json:"modify_time"`
}
// MedalInfo struct .
type MedalInfo struct {
NID int64
GID int64
Name string
Description string
Image string `json:"image"`
ImageSmall string `json:"image_small"`
Condition string
Level int8
LevelRank string `json:"level_rank"`
Sort int8
IsOnline int8 `json:"is_online"`
CTime xtime.Time
MTime string `json:"modify_time"`
}

View File

@@ -0,0 +1,61 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"notify_test.go",
"pendant_test.go",
"service_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/usersuit/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"medal.go",
"notify.go",
"pendant.go",
"service.go",
"vip.go",
],
importpath = "go-common/app/job/main/usersuit/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/job/main/usersuit/conf:go_default_library",
"//app/job/main/usersuit/dao/medal:go_default_library",
"//app/job/main/usersuit/dao/pendant:go_default_library",
"//app/job/main/usersuit/model:go_default_library",
"//app/service/main/vip/model:go_default_library",
"//library/log:go_default_library",
"//library/queue/databus:go_default_library",
"//vendor/github.com/robfig/cron: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"],
)

View File

@@ -0,0 +1,47 @@
package service
import (
"context"
"runtime/debug"
"go-common/app/job/main/usersuit/model"
"go-common/library/log"
)
var (
_upTaskMedal = map[int64]int64{1: 4, 2: 3, 3: 1, 4: 7, 5: 6, 6: 5, 7: 10, 8: 9, 9: 8}
)
func (s *Service) cronUpNameplate() {
defer func() {
if x := recover(); x != nil {
log.Error("lrucleanproc panic %v : %s", x, debug.Stack())
go s.cronUpNameplate()
}
}()
var (
err error
res *model.UpInfo
ctx = context.TODO()
)
if res, err = s.medalDao.UpInfoData(ctx); err != nil {
log.Error("s.medalDao.UpInfoData err(%+v)", err)
return
}
for _, item := range res.Data {
var (
nid int64
ok bool
)
if nid, ok = _upTaskMedal[item.ID]; !ok {
continue
}
for _, mid := range item.Mids {
log.Info("s.medalDao.AddMedalOwner(%d, %d)", mid, nid)
if err = s.medalDao.Grant(ctx, mid, nid); err != nil {
log.Error("s.medalDao.AddMedalOwner(%d, %d) err(%+v)", mid, nid, err)
}
}
}
}

View File

@@ -0,0 +1,18 @@
package service
import (
"context"
"strconv"
"go-common/app/job/main/usersuit/model"
"go-common/library/log"
)
func (s *Service) accNotify(c context.Context, uid int64, Action string) (err error) {
msg := &model.AccountNotify{UID: uid, Type: "update", Action: Action}
if err = s.accountNotifyPub.Send(c, strconv.FormatInt(msg.UID, 10), msg); err != nil {
log.Error("mid(%d) s.accountNotifyPub.Send(%+v,%s) error(%v)", msg.UID, msg, Action, err)
}
log.Info("mid(%d) s.accountNotifyPub.Send(%+v,%s)", msg.UID, msg, Action)
return
}

View File

@@ -0,0 +1,15 @@
package service
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestService_accNotify(t *testing.T) {
Convey("should return err be nil", t, func() {
err := s.accNotify(context.TODO(), 1, "updateMedal")
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,46 @@
package service
import (
"context"
"time"
"go-common/app/job/main/usersuit/model"
"go-common/library/log"
)
var (
t = time.NewTimer(time.Minute * 5)
)
// startexpireproc start
func (s *Service) startexpireproc() {
for range t.C {
s.expiredEquip(context.TODO())
t.Reset(time.Minute * 10)
}
}
// expiredEquip operator equipment info
func (s *Service) expiredEquip(c context.Context) (err error) {
var (
mids []int64
expires = time.Now().Unix()
affected int64
)
if mids, err = s.pendantDao.ExpireEquipPendant(c, expires); err != nil || len(mids) == 0 {
log.Error("s.pendantDao.ExpireEquipPendant(%d) error(%+v)", expires, err)
return
}
for _, mid := range mids {
if affected, err = s.pendantDao.UpEquipMID(c, mid); err != nil || affected == 0 {
log.Error("s.pendantDao.UpEquipMID(%d) error(%+v)", mid, err)
continue
}
s.pendantDao.DelEquipCache(c, mid)
tid := mid
s.addNotify(func() {
s.accNotify(context.TODO(), tid, model.AccountNotifyUpdatePendant)
})
}
return
}

View File

@@ -0,0 +1,15 @@
package service
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestServiceExpiredEquip(t *testing.T) {
Convey("should return err be nil", t, func() {
err := s.expiredEquip(context.TODO())
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,100 @@
package service
import (
"context"
"sync"
"go-common/app/job/main/usersuit/conf"
medalDao "go-common/app/job/main/usersuit/dao/medal"
pendantDao "go-common/app/job/main/usersuit/dao/pendant"
"go-common/library/log"
"go-common/library/queue/databus"
"github.com/robfig/cron"
)
// Service struct of service.
type Service struct {
pendantDao *pendantDao.Dao
medalDao *medalDao.Dao
// conf
c *conf.Config
accountNotifyPub *databus.Databus
vipBinLogSub *databus.Databus
notifych chan func()
// wait group
wg sync.WaitGroup
}
// New create service instance and return.
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
pendantDao: pendantDao.New(c),
medalDao: medalDao.New(c),
accountNotifyPub: databus.New(c.Databus.AccountNotify),
vipBinLogSub: databus.New(c.Databus.VipBinLog),
notifych: make(chan func(), 10240),
}
// this is function
go s.startexpireproc()
s.wg.Add(1)
go s.notifyproc()
s.wg.Add(1)
go s.vipconsumerproc()
t := cron.New()
if len(s.c.Properties.MedalCron) != 0 {
t.AddFunc(s.c.Properties.MedalCron, s.cronUpNameplate)
}
t.Start()
return
}
func (s *Service) addNotify(f func()) {
select {
case s.notifych <- f:
default:
log.Warn("addNotify chan full")
}
}
// notifyproc nofity clear cache
func (s *Service) notifyproc() {
defer s.wg.Done()
for {
f := <-s.notifych
f()
}
}
// Close dao.
func (s *Service) Close() {
if s.pendantDao != nil {
s.pendantDao.Close()
s.medalDao.Close()
}
s.wg.Wait()
}
// Ping check server ok.
func (s *Service) Ping(c context.Context) (err error) {
if err = s.pendantDao.Ping(c); err != nil {
return
}
return
}
// PDTStatStep PDT Stat step
type PDTStatStep struct {
Start, End, Step int64
}
// PDTGHisStep PDT G his
type PDTGHisStep struct {
Start, End, Step int64
}
// PDTOHisStep Order his
type PDTOHisStep struct {
Start, End, Step int64
}

View File

@@ -0,0 +1,21 @@
package service
import (
"flag"
"path/filepath"
"time"
"go-common/app/job/main/usersuit/conf"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../cmd/convey-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}

View File

@@ -0,0 +1,105 @@
package service
import (
"context"
"encoding/json"
"time"
"go-common/app/job/main/usersuit/model"
vipmdl "go-common/app/service/main/vip/model"
"go-common/library/log"
)
const (
_vipGid = 31
_vipUserInfoTable = "vip_user_info"
)
func (s *Service) vipconsumerproc() {
defer s.wg.Done()
var (
msgs = s.vipBinLogSub.Messages()
err error
c = context.TODO()
)
for {
msg, ok := <-msgs
if !ok {
log.Error("s.vipBinLogSub.Message closed")
return
}
msg.Commit()
m := &model.Message{}
if err = json.Unmarshal(msg.Value, m); err != nil {
log.Error("json.Unmarshal(%v) error(%v)", string(msg.Value), err)
continue
}
switch m.Table {
case _vipUserInfoTable:
if m.Action == "update" {
s.dealUserPendantEquip(c, m.New, m.Old)
}
default:
log.Warn("vipBinLogConsumer unknown message action(%s)", m.Table)
}
if err != nil {
log.Error("vipBinLogMessage key(%s) value(%s) partition(%d) offset(%d) commit error(%v)", msg.Key, msg.Value, msg.Partition, msg.Offset, err)
continue
}
log.Info("vipBinLogMessage key(%s) value(%s) partition(%d) offset(%d) commit", msg.Key, msg.Value, msg.Partition, msg.Offset)
}
}
func (s *Service) dealUserPendantEquip(c context.Context, nwMsg []byte, oldMsg []byte) (err error) {
mr := &model.VipInfoMessage{}
if err = json.Unmarshal(nwMsg, mr); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(nwMsg), err)
return
}
var (
gid int64
pe *model.PendantEquip
)
if pe, err = s.pendantDao.PendantEquipMID(c, mr.Mid); err != nil {
log.Error("mid(%d) s.pendantDao.PendantEquipMID error(%v)", mr.Mid, err)
return
}
if pe == nil || pe.Pid == 0 || pe.Expires == 0 {
log.Warn("mid(%d) no equip pendant(%d) expires(%d)", mr.Mid, pe.Pid, pe.Expires)
return
}
if gid, err = s.pendantDao.PendantEquipGidPid(c, pe.Pid); err != nil {
log.Error("mid(%d) pid(%d) s.pendantDao.PendantEquipGidPid error(%v)", mr.Mid, pe.Pid, err)
return
}
if gid != _vipGid {
log.Warn("mid(%d) no equip the vip gid(%d) of pid(%d)", mr.Mid, gid, pe.Pid)
return
}
if mr.VipStatus == vipmdl.VipStatusNotOverTime {
var ts time.Time
if ts, err = time.ParseInLocation(model.TimeFormatSec, mr.VipOverdueTime, time.Local); err != nil {
log.Error("time.ParseInLocation(%s) error(%v)", mr.VipOverdueTime, err)
return
}
if ts.Unix() <= pe.Expires {
log.Warn("mid(%d) pendant equip_time(%d) than vipoverdue_time(%d)", mr.Mid, pe.Expires, ts.Unix())
return
}
if _, err = s.pendantDao.UpEquipExpires(c, mr.Mid, ts.Unix()); err != nil {
log.Error("s.pendantDao.UpEquipExpires(%d,%d) error(%+v)", mr.Mid, ts.Unix(), err)
return
}
} else {
if _, err = s.pendantDao.UpEquipMID(c, mr.Mid); err != nil {
log.Error("s.pendantDao.UpEquipMID(%d) error(%+v)", mr.Mid, err)
return
}
log.Warn("mid(%d) vip status is overtime", mr.Mid)
}
s.pendantDao.DelEquipCache(c, mr.Mid)
s.addNotify(func() {
s.accNotify(context.TODO(), mr.Mid, model.AccountNotifyUpdatePendant)
})
return
}