- add mongo

master v1.0.73
李光春 2 years ago
parent 7a14377892
commit 8a56a93570

@ -9,12 +9,12 @@ import (
)
// CheckManyTask 多任务检查
func (j *JobsGorm) CheckManyTask(ctx context.Context, tx *gorm.DB, vs []jobs_gorm_model.Task) {
func (c *Client) CheckManyTask(ctx context.Context, tx *gorm.DB, vs []jobs_gorm_model.Task) {
if len(vs) > 0 {
for _, v := range vs {
diffInSecondWithAbs := gotime.Current().DiffInSecondWithAbs(gotime.SetCurrent(v.UpdatedAt).Time)
if diffInSecondWithAbs >= v.Frequency*3 {
if j.config.logDebug == true {
if c.config.debug == true {
log.Printf("[jobs.CheckManyTask]每隔%v秒任务%v相差%v秒\n", v.Frequency, v.Id, diffInSecondWithAbs)
}
err := tx.Where("task_id = ?", v.Id).Where("run_id = ?", v.RunId).Delete(&jobs_gorm_model.TaskLogRun{}).Error
@ -27,10 +27,10 @@ func (j *JobsGorm) CheckManyTask(ctx context.Context, tx *gorm.DB, vs []jobs_gor
}
// CheckSingleTask 单任务检查
func (j *JobsGorm) CheckSingleTask(ctx context.Context, tx *gorm.DB, v jobs_gorm_model.Task) {
func (c *Client) CheckSingleTask(ctx context.Context, tx *gorm.DB, v jobs_gorm_model.Task) {
diffInSecondWithAbs := gotime.Current().DiffInSecondWithAbs(gotime.SetCurrent(v.UpdatedAt).Time)
if diffInSecondWithAbs >= v.Frequency*3 {
if j.config.logDebug == true {
if c.config.debug == true {
log.Printf("[jobs.CheckManyTask]每隔%v秒任务%v相差%v秒\n", v.Frequency, v.Id, diffInSecondWithAbs)
}
err := tx.Where("task_id = ?", v.Id).Where("run_id = ?", v.RunId).Delete(&jobs_gorm_model.TaskLogRun{}).Error

@ -0,0 +1,121 @@
package gojobs
import (
"context"
"go.dtapp.net/dorm"
)
// client *dorm.GormClient
type gormClientFun func() *dorm.GormClient
// client *dorm.MongoClient
// databaseName string
type mongoClientFun func() (*dorm.MongoClient, string)
// client *dorm.RedisClient
type redisClientFun func() *dorm.RedisClient
// 前缀
// lockKeyPrefix 锁Key前缀 xxx_lock
// lockKeySeparator 锁Key分隔符 :
// cornKeyPrefix 任务Key前缀 xxx_cron
// cornKeyCustom 任务Key自定义 xxx_cron_自定义 xxx_cron_自定义_*
type redisPrefixFun func() (lockKeyPrefix, lockKeySeparator, cornKeyPrefix, cornKeyCustom string)
// ClientConfig 实例配置
type ClientConfig struct {
GormClientFun gormClientFun // 数据库驱动
MongoClientFun mongoClientFun // 数据库驱动
RedisClientFun redisClientFun // 数据库驱动
RedisPrefixFun redisPrefixFun // 前缀
Debug bool // 日志开关
CurrentIp string // 当前ip
}
// Client 实例
type Client struct {
config struct {
debug bool // 日志开关
runVersion string // 运行版本
os string // 系统类型
arch string // 系统架构
maxProCs int // CPU核数
version string // GO版本
macAddrS string // Mac地址
insideIp string // 内网ip
outsideIp string // 外网ip
}
cache struct {
redisClient *dorm.RedisClient // 数据库
redisLockClient *dorm.RedisClientLock // 锁服务
lockKeyPrefix string // 锁Key前缀 xxx_lock
lockKeySeparator string // 锁Key分隔符 :
cornKeyPrefix string // 任务Key前缀 xxx_cron
cornKeyCustom string // 任务Key自定义
}
db struct {
gormClient *dorm.GormClient // 数据库
mongoClient *dorm.MongoClient // 数据库
mongoDatabaseName string // 数据库名
}
}
// NewClient 创建实例
func NewClient(config *ClientConfig) (*Client, error) {
var ctx = context.Background()
c := &Client{}
c.config.debug = config.Debug
if config.CurrentIp == "" {
return nil, currentIpNoConfig
}
c.config.outsideIp = config.CurrentIp
// 配置信息
c.setConfig(ctx)
gormClient := config.GormClientFun()
if gormClient != nil && gormClient.Db != nil {
c.db.gormClient = gormClient
c.autoMigrateTask()
c.autoMigrateTaskIp()
c.autoMigrateTaskLog()
c.autoMigrateTaskLogRun()
} else {
return nil, gormClientFunNoConfig
}
mongoClient, databaseName := config.MongoClientFun()
if mongoClient != nil && mongoClient.Db != nil {
c.db.mongoClient = mongoClient
if databaseName == "" {
return nil, mongoClientFunNoConfig
}
c.db.mongoDatabaseName = databaseName
c.mongoCreateCollectionTask(ctx)
c.mongoCreateIndexesTask(ctx)
c.mongoCreateIndexesTaskIp(ctx)
c.mongoCreateCollectionTaskLog(ctx)
c.mongoCreateIndexesTaskLog(ctx)
c.mongoCreateCollectionTaskLogRun(ctx)
c.mongoCreateIndexesTaskLogRun(ctx)
}
redisClient := config.RedisClientFun()
if redisClient != nil && redisClient.Db != nil {
c.cache.redisClient = redisClient
c.cache.redisLockClient = c.cache.redisClient.NewLock()
}
c.cache.lockKeyPrefix, c.cache.lockKeySeparator, c.cache.cornKeyPrefix, c.cache.cornKeyCustom = config.RedisPrefixFun()
if c.cache.lockKeyPrefix == "" || c.cache.lockKeySeparator == "" || c.cache.cornKeyPrefix == "" || c.cache.cornKeyCustom == "" {
return nil, redisPrefixFunNoConfig
}
return c, nil
}

@ -0,0 +1,18 @@
package gojobs
import (
"context"
"go.dtapp.net/goarray"
"go.dtapp.net/goip"
"runtime"
)
func (c *Client) setConfig(ctx context.Context) {
c.config.runVersion = Version
c.config.os = runtime.GOOS
c.config.arch = runtime.GOARCH
c.config.maxProCs = runtime.GOMAXPROCS(0)
c.config.version = runtime.Version()
c.config.macAddrS = goarray.TurnString(goip.GetMacAddr(ctx))
c.config.insideIp = goip.GetInsideIp(ctx)
}

@ -1,6 +1,6 @@
package gojobs
const (
Version = "1.0.72"
Version = "1.0.73"
SpecifyIpNull = "0.0.0.0"
)

@ -22,9 +22,9 @@ type ConfigCreateInCustomId struct {
}
// CreateInCustomId 创建正在运行任务
func (j *JobsGorm) CreateInCustomId(config *ConfigCreateInCustomId) error {
func (c *Client) CreateInCustomId(config *ConfigCreateInCustomId) error {
if config.CurrentIp == "" {
config.CurrentIp = j.config.outsideIp
config.CurrentIp = c.config.outsideIp
}
err := config.Tx.Create(&jobs_gorm_model.Task{
Status: TASK_IN,
@ -60,13 +60,13 @@ type ConfigCreateInCustomIdOnly struct {
}
// CreateInCustomIdOnly 创建正在运行唯一任务
func (j *JobsGorm) CreateInCustomIdOnly(config *ConfigCreateInCustomIdOnly) error {
query := j.TaskTypeTakeIn(config.Tx, config.CustomId, config.Type)
func (c *Client) CreateInCustomIdOnly(config *ConfigCreateInCustomIdOnly) error {
query := c.TaskTypeTakeIn(config.Tx, config.CustomId, config.Type)
if query.Id != 0 {
return errors.New(fmt.Sprintf("%d:[%s@%s]任务已存在", query.Id, config.CustomId, config.Type))
}
if config.CurrentIp == "" {
config.CurrentIp = j.config.outsideIp
config.CurrentIp = c.config.outsideIp
}
err := config.Tx.Create(&jobs_gorm_model.Task{
Status: TASK_IN,
@ -103,9 +103,9 @@ type ConfigCreateInCustomIdMaxNumber struct {
}
// CreateInCustomIdMaxNumber 创建正在运行任务并限制数量
func (j *JobsGorm) CreateInCustomIdMaxNumber(config *ConfigCreateInCustomIdMaxNumber) error {
func (c *Client) CreateInCustomIdMaxNumber(config *ConfigCreateInCustomIdMaxNumber) error {
if config.CurrentIp == "" {
config.CurrentIp = j.config.outsideIp
config.CurrentIp = c.config.outsideIp
}
err := config.Tx.Create(&jobs_gorm_model.Task{
Status: TASK_IN,
@ -143,13 +143,13 @@ type ConfigCreateInCustomIdMaxNumberOnly struct {
}
// CreateInCustomIdMaxNumberOnly 创建正在运行唯一任务并限制数量
func (j *JobsGorm) CreateInCustomIdMaxNumberOnly(config *ConfigCreateInCustomIdMaxNumberOnly) error {
query := j.TaskTypeTakeIn(config.Tx, config.CustomId, config.Type)
func (c *Client) CreateInCustomIdMaxNumberOnly(config *ConfigCreateInCustomIdMaxNumberOnly) error {
query := c.TaskTypeTakeIn(config.Tx, config.CustomId, config.Type)
if query.Id != 0 {
return errors.New(fmt.Sprintf("%d:[%s@%s]任务已存在", query.Id, config.CustomId, config.Type))
}
if config.CurrentIp == "" {
config.CurrentIp = j.config.outsideIp
config.CurrentIp = c.config.outsideIp
}
err := config.Tx.Create(&jobs_gorm_model.Task{
Status: TASK_IN,

@ -22,9 +22,9 @@ type ConfigCreateWaitCustomId struct {
}
// CreateWaitCustomId 创建正在运行任务
func (j *JobsGorm) CreateWaitCustomId(config *ConfigCreateWaitCustomId) error {
func (c *Client) CreateWaitCustomId(config *ConfigCreateWaitCustomId) error {
if config.CurrentIp == "" {
config.CurrentIp = j.config.outsideIp
config.CurrentIp = c.config.outsideIp
}
err := config.Tx.Create(&jobs_gorm_model.Task{
Status: TASK_WAIT,

@ -0,0 +1,10 @@
package gojobs
import "errors"
var (
currentIpNoConfig = errors.New("请配置 CurrentIp")
mongoClientFunNoConfig = errors.New("请配置 MongoClientFun")
redisPrefixFunNoConfig = errors.New("请配置 RedisPrefixFun")
gormClientFunNoConfig = errors.New("请配置 GormClientFun")
)

@ -0,0 +1,32 @@
package gojobs
import (
"github.com/go-redis/redis/v9"
"go.mongodb.org/mongo-driver/mongo"
"gorm.io/gorm"
)
// GetDb 获取数据库驱动
func (c *Client) GetDb() *gorm.DB {
return c.db.gormClient.Db
}
// GetMongoDb 获取数据库驱动
func (c *Client) GetMongoDb() *mongo.Client {
return c.db.mongoClient.Db
}
// GetRedis 获取缓存数据库驱动
func (c *Client) GetRedis() *redis.Client {
return c.cache.redisClient.Db
}
// GetCurrentIp 获取当前ip
func (c *Client) GetCurrentIp() string {
return c.config.outsideIp
}
// GetSubscribeAddress 获取订阅地址
func (c *Client) GetSubscribeAddress() string {
return c.cache.cornKeyPrefix + "_" + c.cache.cornKeyCustom
}

@ -9,12 +9,10 @@ require (
go.dtapp.net/dorm v1.0.30
go.dtapp.net/goarray v1.0.1
go.dtapp.net/goip v1.0.28
go.dtapp.net/golog v1.0.51
go.dtapp.net/gostring v1.0.10
go.dtapp.net/gotime v1.0.5
go.dtapp.net/gotrace_id v1.0.6
google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.1
go.mongodb.org/mongo-driver v1.10.1
gorm.io/gorm v1.23.8
)
@ -31,7 +29,6 @@ require (
github.com/go-playground/validator/v10 v10.11.0 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/goccy/go-json v0.9.11 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
@ -48,15 +45,12 @@ require (
github.com/klauspost/compress v1.15.9 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/lib/pq v1.10.6 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.6.6 // indirect
github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rs/zerolog v1.28.0 // indirect
github.com/saracen/go7z v0.0.0-20191010121135-9c09b6bd7fda // indirect
github.com/saracen/solidblock v0.0.0-20190426153529-45df20abab6f // indirect
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
@ -78,25 +72,20 @@ require (
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.dtapp.net/gorandom v1.0.1 // indirect
go.dtapp.net/gorequest v1.0.28 // indirect
go.dtapp.net/gourl v1.0.0 // indirect
go.dtapp.net/goxml v1.0.1 // indirect
go.mongodb.org/mongo-driver v1.10.1 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.23.0 // indirect
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b // indirect
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gorm.io/datatypes v1.0.7 // indirect
gorm.io/driver/mysql v1.3.6 // indirect
gorm.io/driver/postgres v1.3.9 // indirect
mellium.im/sasl v0.3.0 // indirect
modernc.org/ccgo/v3 v3.16.8 // indirect
modernc.org/libc v1.16.19 // indirect
modernc.org/sqlite v1.18.0 // indirect
xorm.io/builder v0.3.12 // indirect
xorm.io/xorm v1.3.1 // indirect
)

@ -3,10 +3,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
@ -32,7 +28,6 @@ github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUK
github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
github.com/beego/beego/v2 v2.0.5 h1:fa2TBWfKGDs35Ck9an9SVnpS0zM8sRTXlW8rFjpeYlE=
github.com/beego/beego/v2 v2.0.5/go.mod h1:CH2/JIaB4ceGYVQlYqTAFft4pVk/ol1ZkakUrUvAyns=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@ -54,7 +49,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
@ -64,12 +58,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU=
github.com/denisenkom/go-mssqldb v0.12.2 h1:1OcPn5GBIobjWNd+8yjfHNIaFX14B1pWI3F9HZy5KXw=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
@ -115,7 +106,6 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
@ -124,10 +114,6 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4=
github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -136,8 +122,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@ -320,9 +304,6 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@ -330,12 +311,10 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
@ -353,13 +332,10 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v64GQ=
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
@ -395,7 +371,6 @@ github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaF
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -433,11 +408,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
@ -530,8 +502,6 @@ go.dtapp.net/goarray v1.0.1 h1:cHNHaJ2MFcuJPA1WKU2PM1EUZShS1vQqEH7n6YXsQVU=
go.dtapp.net/goarray v1.0.1/go.mod h1:/MPhlFCAhQyeNV1M0v1PAOOX33Sg705fVjUgMO12IBQ=
go.dtapp.net/goip v1.0.28 h1:wZt+wbzNhOLRUJnepG4c8HhUr4V9jNXOF6wJ1h7jUvU=
go.dtapp.net/goip v1.0.28/go.mod h1:ZqPPUvpOSzdtB/dEZFiaD0CBRZmvIzjDmm3XkpMC9Bo=
go.dtapp.net/golog v1.0.51 h1:FIXZdwN+Vn4mj7QafY4w/BKQiliER8DrWt5BjJ14kOU=
go.dtapp.net/golog v1.0.51/go.mod h1:aXer1I0jFUFfcNKeftAf0S6yKT86dhQ8manUWXIJ2ZE=
go.dtapp.net/gorandom v1.0.1 h1:IWfMClh1ECPvyUjlqD7MwLq4mZdUusD1qAwAdsvEJBs=
go.dtapp.net/gorandom v1.0.1/go.mod h1:ZPdgalKpvFV/ATQqR0k4ns/F/IpITAZpx6WkWirr5Y8=
go.dtapp.net/gorequest v1.0.28 h1:EehFtF5WcvyZ9rB6MAQoI2kJkhR8Wv8tVgpoxXcb3sI=
@ -542,10 +512,6 @@ go.dtapp.net/gotime v1.0.5 h1:12aNgB2ULpP6QgQHEUkLilZ4ASvhpFxMFQkBwn0par8=
go.dtapp.net/gotime v1.0.5/go.mod h1:Gq7eNLr2iMLP18UNWONRq4V3Uhf/ADp4bIrS+Tc6ktY=
go.dtapp.net/gotrace_id v1.0.6 h1:q6s8jy50vt1820b69JKQaFqbhGS5yJGMVtocwOGOPO0=
go.dtapp.net/gotrace_id v1.0.6/go.mod h1:o5kSzNK4s3GrrKpkRKXtAhArtBG1e5N5O5KGPlBlWG4=
go.dtapp.net/gourl v1.0.0 h1:Zbe0GiMFyyRy2+bjbVsYulakH5d58w3CDZkUPonlMoQ=
go.dtapp.net/gourl v1.0.0/go.mod h1:x9A/pJ3iKDTb6Gu2RtJy2iHg56IowXIcIGQdogqpGjs=
go.dtapp.net/goxml v1.0.1 h1:WODsjNpmHTtoeLsXgOjC81qRbu4aXZ3LKBHApNGaPjY=
go.dtapp.net/goxml v1.0.1/go.mod h1:duD2uvBofiu/Rer1XQH2FyUhIkj6Zjapp4NDwRvoiQE=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.mongodb.org/mongo-driver v1.10.1 h1:NujsPveKwHaWuKUer/ceo9DzEe7HIj1SlJ6uvXZG0S4=
@ -557,21 +523,13 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -585,14 +543,12 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@ -629,7 +585,6 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
@ -674,7 +629,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -726,8 +680,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf h1:Q5xNKbTSFwkuaaGaR7CMcXEM5sy19KYdUU8iF8/iRC0=
google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
@ -737,10 +689,7 @@ google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw=
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
@ -755,7 +704,6 @@ gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
@ -763,27 +711,16 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/datatypes v1.0.7 h1:8NhJN4+annFjwV1WufDhFiPjdUvV1lSGUdg1UCjQIWY=
gorm.io/datatypes v1.0.7/go.mod h1:l9qkCuy0CdzDEop9HKUdcnC9gHC2sRlaFtHkTzsZRqg=
gorm.io/driver/mysql v1.3.2/go.mod h1:ChK6AHbHgDCFZyJp0F+BmVGb06PSIoh9uVYKAlRbb2U=
gorm.io/driver/mysql v1.3.6 h1:BhX1Y/RyALb+T9bZ3t07wLnPZBukt+IRkMn8UZSNbGM=
gorm.io/driver/mysql v1.3.6/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
gorm.io/driver/postgres v1.3.4/go.mod h1:y0vEuInFKJtijuSGu9e5bs5hzzSzPK+LancpKpvbRBw=
gorm.io/driver/postgres v1.3.9 h1:lWGiVt5CijhQAg0PWB7Od1RNcBw/jS4d2cAScBcSDXg=
gorm.io/driver/postgres v1.3.9/go.mod h1:qw/FeqjxmYqW5dBcYNBsnhQULIApQdk7YuuDPktVi1U=
gorm.io/driver/sqlite v1.3.1/go.mod h1:wJx0hJspfycZ6myN38x1O/AqLtNS6c5o9TndewFbELg=
gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ=
gorm.io/driver/sqlserver v1.3.1/go.mod h1:w25Vrx2BG+CJNUu/xKbFhaKlGxT/nzRkhWCCoptX8tQ=
gorm.io/driver/sqlserver v1.3.2 h1:yYt8f/xdAKLY7lCCyXxIUEgZ/WsURos3dHrx8MKFGAk=
gorm.io/gorm v1.23.1/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.6/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.7/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE=
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
@ -903,6 +840,7 @@ modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=
modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=
modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
modernc.org/libc v1.16.19 h1:S8flPn5ZeXx6iw/8yNa986hwTQDrY8RXU7tObZuAozo=
modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
modernc.org/lldb v1.0.2/go.mod h1:ovbKqyzA9H/iPwHkAOH0qJbIQVT9rlijecenxDwVUi0=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
@ -920,6 +858,7 @@ modernc.org/ql v1.4.0/go.mod h1:q4c29Bgdx+iAtxx47ODW5Xo2X0PDkjSCK9NdQl6KFxc=
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
modernc.org/sqlite v1.14.2/go.mod h1:yqfn85u8wVOE6ub5UT8VI9JjhrwBUUCNyTACN0h6Sx8=
modernc.org/sqlite v1.18.0 h1:ef66qJSgKeyLyrF4kQ2RHw/Ue3V89fyFNbGL073aDjI=
modernc.org/sqlite v1.18.0/go.mod h1:B9fRWZacNxJBHoCJZQr1R54zhVn3fjfl0aszflrTSxY=
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
modernc.org/strutil v1.1.2 h1:iFBDH6j1Z0bN/Q9udJnnFoFpENA4252qe/7/5woE5MI=
modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY=

@ -0,0 +1,219 @@
package gojobs
import (
"go.dtapp.net/gojobs/jobs_gorm_model"
"gorm.io/gorm"
"log"
"strings"
)
// TaskTakeId 查询单任务
func (c *Client) TaskTakeId(tx *gorm.DB, id uint) (result jobs_gorm_model.Task) {
tx.Where("id = ?", id).Take(&result)
return result
}
// TaskTake 查询单任务
func (c *Client) TaskTake(tx *gorm.DB, customId string) (result jobs_gorm_model.Task) {
tx.Where("custom_id = ?", customId).Take(&result)
return result
}
// 查询单任务
func (c *Client) taskTake(tx *gorm.DB, customId, status string) (result jobs_gorm_model.Task) {
tx.Where("custom_id = ?", customId).Where("status = ?", status).Take(&result)
return result
}
// TaskTakeIn 查询单任务 - 任务运行
func (c *Client) TaskTakeIn(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return c.taskTake(tx, customId, TASK_IN)
}
// TaskTakeSuccess 查询单任务 - 任务完成
func (c *Client) TaskTakeSuccess(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return c.taskTake(tx, customId, TASK_SUCCESS)
}
// TaskTakeError 查询单任务 - 任务异常
func (c *Client) TaskTakeError(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return c.taskTake(tx, customId, TASK_ERROR)
}
// TaskTakeTimeout 查询单任务 - 任务超时
func (c *Client) TaskTakeTimeout(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return c.taskTake(tx, customId, TASK_TIMEOUT)
}
// TaskTakeWait 查询单任务 - 任务等待
func (c *Client) TaskTakeWait(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return c.taskTake(tx, customId, TASK_WAIT)
}
// TaskTypeTake 查询单任务
func (c *Client) TaskTypeTake(tx *gorm.DB, customId, Type string) (result jobs_gorm_model.Task) {
tx.Where("custom_id = ?", customId).Where("type = ?", Type).Take(&result)
return result
}
// 查询单任务
func (c *Client) taskTypeTake(tx *gorm.DB, customId, Type, status string) (result jobs_gorm_model.Task) {
tx.Where("custom_id = ?", customId).Where("type = ?", Type).Where("status = ?", status).Take(&result)
return result
}
// TaskTypeTakeIn 查询单任务 - 任务运行
func (c *Client) TaskTypeTakeIn(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return c.taskTypeTake(tx, customId, Type, TASK_IN)
}
// TaskTypeTakeSuccess 查询单任务 - 任务完成
func (c *Client) TaskTypeTakeSuccess(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return c.taskTypeTake(tx, customId, Type, TASK_SUCCESS)
}
// TaskTypeTakeError 查询单任务 - 任务异常
func (c *Client) TaskTypeTakeError(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return c.taskTypeTake(tx, customId, Type, TASK_ERROR)
}
// TaskTypeTakeTimeout 查询单任务 - 任务超时
func (c *Client) TaskTypeTakeTimeout(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return c.taskTypeTake(tx, customId, Type, TASK_TIMEOUT)
}
// TaskTypeTakeWait 查询单任务 - 任务等待
func (c *Client) TaskTypeTakeWait(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return c.taskTypeTake(tx, customId, Type, TASK_WAIT)
}
// TaskFindAll 查询多任务
func (c *Client) TaskFindAll(tx *gorm.DB, frequency int64) (results []jobs_gorm_model.Task) {
tx.Where("frequency = ?", frequency).Order("id asc").Find(&results)
return results
}
// 查询多任务
func (c *Client) taskFindAll(tx *gorm.DB, frequency int64, status string) (results []jobs_gorm_model.Task) {
tx.Where("frequency = ?", frequency).Where("status = ?", status).Order("id asc").Find(&results)
return results
}
// TaskFindAllIn 查询多任务 - 任务运行
func (c *Client) TaskFindAllIn(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return c.taskFindAll(tx, frequency, TASK_IN)
}
// TaskFindAllSuccess 查询多任务 - 任务完成
func (c *Client) TaskFindAllSuccess(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return c.taskFindAll(tx, frequency, TASK_SUCCESS)
}
// TaskFindAllError 查询多任务 - 任务异常
func (c *Client) TaskFindAllError(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return c.taskFindAll(tx, frequency, TASK_ERROR)
}
// TaskFindAllTimeout 查询多任务 - 任务超时
func (c *Client) TaskFindAllTimeout(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return c.taskFindAll(tx, frequency, TASK_TIMEOUT)
}
// TaskFindAllWait 查询多任务 - 任务等待
func (c *Client) TaskFindAllWait(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return c.taskFindAll(tx, frequency, TASK_WAIT)
}
// StartTask 任务启动
func (c *Client) StartTask(tx *gorm.DB, id uint) error {
return c.EditTask(tx, id).
Select("status", "status_desc").
Updates(jobs_gorm_model.Task{
Status: TASK_IN,
StatusDesc: "启动任务",
}).Error
}
// StartTaskCustom 任务启动自定义
func (c *Client) StartTaskCustom(tx *gorm.DB, customId string, customSequence int64) error {
return tx.Model(&jobs_gorm_model.Task{}).
Where("custom_id = ?", customId).
Where("custom_sequence = ?", customSequence).
Where("status = ?", TASK_WAIT).
Select("status", "status_desc").
Updates(jobs_gorm_model.Task{
Status: TASK_IN,
StatusDesc: "启动任务",
}).Error
}
// EditTask 任务修改
func (c *Client) EditTask(tx *gorm.DB, id uint) *gorm.DB {
return tx.Model(&jobs_gorm_model.Task{}).Where("id = ?", id)
}
// UpdateFrequency 更新任务频率
func (c *Client) UpdateFrequency(tx *gorm.DB, id uint, frequency int64) *gorm.DB {
return c.EditTask(tx, id).
Select("frequency").
Updates(jobs_gorm_model.Task{
Frequency: frequency,
})
}
func (c *Client) taskIpTake(tx *gorm.DB, taskType, ips string) (result jobs_gorm_model.TaskIp) {
tx.Where("task_type = ?", taskType).Where("ips = ?", ips).Take(&result)
return result
}
// TaskIpUpdate 更新ip
func (c *Client) TaskIpUpdate(tx *gorm.DB, taskType, ips string) *gorm.DB {
query := c.taskIpTake(tx, taskType, ips)
if query.Id != 0 {
return tx
}
updateStatus := tx.Create(&jobs_gorm_model.TaskIp{
TaskType: taskType,
Ips: ips,
})
if updateStatus.RowsAffected == 0 {
log.Println("任务更新失败:", updateStatus.Error)
}
return updateStatus
}
// TaskIpInit 实例任务ip
func (c *Client) TaskIpInit(tx *gorm.DB, ips map[string]string) bool {
if c.config.outsideIp == "" || c.config.outsideIp == "0.0.0.0" {
return false
}
tx.Where("ips = ?", c.config.outsideIp).Delete(&jobs_gorm_model.TaskIp{}) // 删除
for k, v := range ips {
if v == "" {
c.TaskIpUpdate(tx, k, c.config.outsideIp)
} else {
find := strings.Contains(v, ",")
if find == true {
// 包含
parts := strings.Split(v, ",")
for _, vv := range parts {
if vv == c.config.outsideIp {
c.TaskIpUpdate(tx, k, c.config.outsideIp)
}
}
} else {
// 不包含
if v == c.config.outsideIp {
c.TaskIpUpdate(tx, k, c.config.outsideIp)
}
}
}
}
return true
}
// TaskLogRunTake 查询任务执行日志
func (c *Client) TaskLogRunTake(tx *gorm.DB, taskId uint, runId string) (result jobs_gorm_model.TaskLogRun) {
tx.Select("id", "os", "arch", "outside_ip", "created_at").Where("task_id = ?", taskId).Where("run_id = ?", runId).Take(&result)
return result
}

@ -1,21 +0,0 @@
package gojobs
import (
"context"
"fmt"
"go.dtapp.net/goip"
)
var ip string
func configIp() {
ip = goip.GetOutsideIp(context.Background())
}
const prefix = "cron:"
const prefixIp = "cron_%s:"
func prefixSprintf(str string) string {
return fmt.Sprintf(prefixIp, str)
}

@ -1,38 +0,0 @@
package gojobs
import (
"google.golang.org/grpc"
)
// ClientConfig 客户端配置
type ClientConfig struct {
Address string // 服务端口 127.0.0.1:8888
}
// Client 定时任务
type Client struct {
ClientConfig // 配置
Conn *grpc.ClientConn // 链接信息
}
// NewClient 创建客户端
func NewClient(config *ClientConfig) *Client {
if config.Address == "" {
panic("[客户端]请填写服务端口")
}
c := &Client{}
c.Address = config.Address
var err error
// 建立连接 获取client
c.Conn, err = grpc.Dial(c.Address, grpc.WithInsecure())
if err != nil {
panic("[客户端]{连接失败}" + err.Error())
}
return c
}

@ -1,56 +0,0 @@
package gojobs
import (
"context"
"go.dtapp.net/gojobs/pb"
"google.golang.org/grpc"
"log"
)
// CronConfig 定时任务配置
type CronConfig struct {
Address string // 服务端口 127.0.0.1:8888
}
// GrpcCron 定时任务
type GrpcCron struct {
CronConfig // 配置
Pub pb.PubSubClient // 订阅
Conn *grpc.ClientConn // 链接信息
}
// NewGrpcCron 创建定时任务
func NewGrpcCron(config *CronConfig) *GrpcCron {
if config.Address == "" {
panic("[定时任务]请填写服务端口")
}
c := &GrpcCron{}
c.Address = config.Address
var err error
// 建立连接 获取client
c.Conn, err = grpc.Dial(c.Address, grpc.WithInsecure())
if err != nil {
panic("[定时任务]{连接失败}" + err.Error())
}
// 新建一个客户端
c.Pub = pb.NewPubSubClient(c.Conn)
return c
}
// Send 发送
func (c *GrpcCron) Send(in *pb.PublishRequest) (*pb.PublishResponse, error) {
log.Printf("[定时任务]{广播开始}编号:%s 类型:%s ip%s\n", in.GetId(), in.GetValue(), in.GetIp())
stream, err := c.Pub.Publish(context.Background(), in)
if err != nil {
log.Printf("[定时任务]{广播失败}编号:%s %v\n", in.GetId(), err)
}
log.Printf("[定时任务]{广播成功}编号:%s 类型:%s ip%s\n", in.GetId(), in.GetValue(), in.GetIp())
return stream, err
}

@ -1,84 +0,0 @@
package gojobs
import (
"errors"
"go.dtapp.net/gojobs/pb"
"go.dtapp.net/gojobs/pubsub"
"google.golang.org/grpc"
"log"
"net"
"strings"
"time"
)
// ServerConfig 服务配置
type ServerConfig struct {
PublishTimeout time.Duration // 控制发布时最大阻塞时间
PubBuffer int // 缓冲区大小控制每个订阅者的chan缓冲区大小
Address string // 服务端口 0.0.0.0:8888
}
// Server 服务
type Server struct {
ServerConfig // 配置
Pub *pubsub.Publisher // 订阅
Conn *grpc.Server // 链接信息
}
// NewServer 创建服务和注册
func NewServer(config *ServerConfig) *Server {
if config.Address == "" {
panic("[服务中转]请填写服务端口")
}
s := &Server{}
s.PublishTimeout = config.PublishTimeout
s.PubBuffer = config.PubBuffer
s.Address = config.Address
s.Pub = pubsub.NewPublisher(config.PublishTimeout, config.PubBuffer)
// 创建gRPC服务器
s.Conn = grpc.NewServer()
// 注册
pb.RegisterPubSubServer(s.Conn, pb.NewPubSubServerService())
return s
}
// StartCron 启动定时任务
func (s *Server) StartCron() {
cron := s.Pub.SubscribeTopic(func(v interface{}) bool {
if key, ok := v.(string); ok {
if strings.HasPrefix(key, prefix) {
return true
}
}
return false
})
go func() {
log.Println("crontopic:", <-cron)
}()
}
// StartUp 启动服务
func (s *Server) StartUp() {
// 监听本地端口
lis, err := net.Listen("tcp", s.Address)
if err != nil {
panic(errors.New("[服务中转]{创建监听失败}" + err.Error()))
}
log.Println("[服务中转]{监听}", lis.Addr())
// 启动grpc
err = s.Conn.Serve(lis)
if err != nil {
panic(errors.New("[服务中转]{创建服务失败}" + err.Error()))
}
}

@ -1,76 +0,0 @@
package gojobs
import (
"context"
"go.dtapp.net/gojobs/pb"
"go.dtapp.net/gostring"
"google.golang.org/grpc"
)
// WorkerConfig 工作配置
type WorkerConfig struct {
Address string // 服务端口 127.0.0.1:8888
ClientIp string // 自己的ip地址
}
// Worker 工作
type Worker struct {
WorkerConfig // 配置
Pub pb.PubSubClient // 订阅
Conn *grpc.ClientConn // 链接信息
}
// NewWorker 创建工作
func NewWorker(config *WorkerConfig) *Worker {
if config.Address == "" {
panic("[工作线]请填写服务端口")
}
if config.ClientIp == "" {
panic("[定时任务]请填写ip地址")
}
w := &Worker{}
w.Address = config.Address
w.ClientIp = config.ClientIp
var err error
// 建立连接 获取client
w.Conn, err = grpc.Dial(w.Address, grpc.WithInsecure())
if err != nil {
panic("[工作线]{连接失败}" + err.Error())
}
// 新建一个客户端
w.Pub = pb.NewPubSubClient(w.Conn)
return w
}
// SubscribeCron 订阅服务
func (w *Worker) SubscribeCron() pb.PubSub_SubscribeClient {
stream, err := w.Pub.Subscribe(context.Background(), &pb.SubscribeRequest{
Id: gostring.GetUuId(),
Value: prefix,
Ip: w.ClientIp,
})
if err != nil {
panic("[工作线]{订阅服务失败}" + err.Error())
}
return stream
}
// StartCron 启动任务
func (w *Worker) StartCron() pb.PubSub_SubscribeClient {
stream, err := w.Pub.Subscribe(context.Background(), &pb.SubscribeRequest{
Id: gostring.GetUuId(),
Value: prefixSprintf(w.ClientIp),
Ip: w.ClientIp,
})
if err != nil {
panic("[工作线]{启动任务失败}" + err.Error())
}
return stream
}

21
ip.go

@ -0,0 +1,21 @@
package gojobs
import (
"context"
"go.dtapp.net/goip"
"go.dtapp.net/gojobs/jobs_gorm_model"
"gorm.io/gorm"
)
// RefreshIp 刷新Ip
func (c *Client) RefreshIp(ctx context.Context, tx *gorm.DB) {
xip := goip.GetOutsideIp(ctx)
if c.config.outsideIp == "" || c.config.outsideIp == "0.0.0.0" {
return
}
if c.config.outsideIp == xip {
return
}
tx.Where("ips = ?", c.config.outsideIp).Delete(&jobs_gorm_model.TaskIp{}) // 删除
c.config.outsideIp = xip
}

@ -1,116 +0,0 @@
package gojobs
import (
"context"
"errors"
"fmt"
"go.dtapp.net/dorm"
"go.dtapp.net/goarray"
"go.dtapp.net/goip"
"go.dtapp.net/gojobs/jobs_gorm_model"
"go.dtapp.net/golog"
"log"
"runtime"
)
type JobsGormConfig struct {
GormClient *dorm.GormClient // 数据库驱动
RedisClient *dorm.RedisClient // 缓存数据库驱动
LogClient *golog.ZapLog // 日志驱动
LogDebug bool // 日志开关
CurrentIp string // 当前ip
LockKeyPrefix string // 锁Key前缀 xxx_lock
LockKeySeparator string // 锁Key分隔符 :
CornKeyPrefix string // 任务Key前缀 xxx_cron
CornKeyCustom string // 任务Key自定义 xxx_cron_自定义 xxx_cron_自定义_*
}
// JobsGorm Gorm数据库驱动
type JobsGorm struct {
gormClient *dorm.GormClient // 数据库服务
redisClient *dorm.RedisClient // 缓存服务
lockClient *dorm.RedisClientLock // 锁服务
logClient *golog.ZapLog // 日志服务
config struct {
logDebug bool // 日志开关
runVersion string // 运行版本
os string // 系统类型
arch string // 系统架构
maxProCs int // CPU核数
version string // GO版本
macAddrS string // Mac地址
insideIp string // 内网ip
outsideIp string // 外网ip
lockKeyPrefix string // 锁Key前缀 xxx_lock
lockKeySeparator string // 锁Key分隔符 :
cornKeyPrefix string // 任务Key前缀 xxx_cron
cornKeyCustom string // 任务Key自定义
}
}
// NewJobsGorm 初始化
func NewJobsGorm(config *JobsGormConfig) (*JobsGorm, error) {
// 判断
if config.LockKeyPrefix == "" {
return nil, errors.New("需要配置锁Key前缀")
}
if config.LockKeySeparator == "" {
return nil, errors.New("需要配置锁Key分隔符")
}
if config.CornKeyPrefix == "" {
return nil, errors.New("需要配置任务Key前缀")
}
if config.CornKeyCustom == "" {
return nil, errors.New("需要配置任务Key自定义")
}
if config.CurrentIp == "" {
return nil, errors.New("需要配置当前的IP")
}
if config.GormClient.Db == nil {
return nil, errors.New("需要配置数据库驱动")
}
if config.RedisClient.Db == nil {
return nil, errors.New("需要配置缓存数据库驱动")
}
c := &JobsGorm{}
c.gormClient = config.GormClient
c.redisClient = config.RedisClient
c.lockClient = c.redisClient.NewLock()
c.logClient = config.LogClient
c.config.outsideIp = config.CurrentIp
c.config.lockKeyPrefix = config.LockKeyPrefix
c.config.lockKeySeparator = config.LockKeySeparator
c.config.cornKeyPrefix = config.CornKeyPrefix
c.config.cornKeyCustom = config.CornKeyCustom
c.config.logDebug = config.LogDebug
// 配置信息
c.config.runVersion = Version
c.config.os = runtime.GOOS
c.config.arch = runtime.GOARCH
c.config.maxProCs = runtime.GOMAXPROCS(0)
c.config.version = runtime.Version()
c.config.macAddrS = goarray.TurnString(goip.GetMacAddr(context.Background()))
c.config.insideIp = goip.GetInsideIp(context.Background())
// 创建模型
err := c.gormClient.Db.AutoMigrate(
&jobs_gorm_model.Task{},
&jobs_gorm_model.TaskLog{},
&jobs_gorm_model.TaskLogRun{},
&jobs_gorm_model.TaskIp{},
)
if err != nil {
return nil, errors.New(fmt.Sprintf("创建任务模型失败:%v\n", err))
}
if c.config.logDebug == true {
log.Printf("[jobs.NewJobsGorm]%+v\n", c.config)
}
return c, nil
}

@ -1,26 +0,0 @@
package gojobs
import (
"github.com/go-redis/redis/v9"
"gorm.io/gorm"
)
// GetDb 获取数据库驱动
func (j *JobsGorm) GetDb() *gorm.DB {
return j.gormClient.Db
}
// GetRedis 获取缓存数据库驱动
func (j *JobsGorm) GetRedis() *redis.Client {
return j.redisClient.Db
}
// GetCurrentIp 获取当前ip
func (j *JobsGorm) GetCurrentIp() string {
return j.config.outsideIp
}
// GetSubscribeAddress 获取订阅地址
func (j *JobsGorm) GetSubscribeAddress() string {
return j.config.cornKeyPrefix + "_" + j.config.cornKeyCustom
}

@ -1,21 +0,0 @@
package gojobs
import (
"context"
"go.dtapp.net/goip"
"go.dtapp.net/gojobs/jobs_gorm_model"
"gorm.io/gorm"
)
// RefreshIp 刷新Ip
func (j *JobsGorm) RefreshIp(ctx context.Context, tx *gorm.DB) {
xip := goip.GetOutsideIp(ctx)
if j.config.outsideIp == "" || j.config.outsideIp == "0.0.0.0" {
return
}
if j.config.outsideIp == xip {
return
}
tx.Where("ips = ?", j.config.outsideIp).Delete(&jobs_gorm_model.TaskIp{}) // 删除
j.config.outsideIp = xip
}

@ -1,24 +0,0 @@
package gojobs
import (
"context"
"fmt"
"go.dtapp.net/gojobs/jobs_gorm_model"
"go.dtapp.net/gotime"
"time"
)
// Lock 上锁
func (j *JobsGorm) Lock(ctx context.Context, info jobs_gorm_model.Task, id any) (string, error) {
return j.lockClient.Lock(ctx, fmt.Sprintf("%s%s%v%s%v", j.config.lockKeyPrefix, j.config.lockKeySeparator, info.Type, j.config.lockKeySeparator, id), fmt.Sprintf("已在%s@%s机器上锁成功%v", j.config.insideIp, j.config.outsideIp, gotime.Current().Format()), time.Duration(info.Frequency)*3*time.Second)
}
// Unlock Lock 解锁
func (j *JobsGorm) Unlock(ctx context.Context, info jobs_gorm_model.Task, id any) error {
return j.lockClient.Unlock(ctx, fmt.Sprintf("%s%s%v%s%v", j.config.lockKeyPrefix, j.config.lockKeySeparator, info.Type, j.config.lockKeySeparator, id))
}
// LockForever 永远上锁
func (j *JobsGorm) LockForever(ctx context.Context, info jobs_gorm_model.Task, id any) (string, error) {
return j.lockClient.LockForever(ctx, fmt.Sprintf("%s%s%v%s%v", j.config.lockKeyPrefix, j.config.lockKeySeparator, info.Type, j.config.lockKeySeparator, id), fmt.Sprintf("已在%s@%s机器永远上锁成功%v", j.config.insideIp, j.config.outsideIp, gotime.Current().Format()))
}

@ -1,24 +0,0 @@
package gojobs
import (
"context"
"fmt"
"go.dtapp.net/gojobs/jobs_gorm_model"
"go.dtapp.net/gotime"
"time"
)
// LockId 上锁
func (j *JobsGorm) LockId(ctx context.Context, info jobs_gorm_model.Task) (string, error) {
return j.lockClient.Lock(ctx, fmt.Sprintf("%s%s%v%s%v", j.config.lockKeyPrefix, j.config.lockKeySeparator, info.Type, j.config.lockKeySeparator, info.Id), fmt.Sprintf("已在%s@%s机器上锁成功%v", j.config.insideIp, j.config.outsideIp, gotime.Current().Format()), time.Duration(info.Frequency)*3*time.Second)
}
// UnlockId Lock 解锁
func (j *JobsGorm) UnlockId(ctx context.Context, info jobs_gorm_model.Task) error {
return j.lockClient.Unlock(ctx, fmt.Sprintf("%s%s%v%s%v", j.config.lockKeyPrefix, j.config.lockKeySeparator, info.Type, j.config.lockKeySeparator, info.Id))
}
// LockForeverId 永远上锁
func (j *JobsGorm) LockForeverId(ctx context.Context, info jobs_gorm_model.Task) (string, error) {
return j.lockClient.LockForever(ctx, fmt.Sprintf("%s%s%v%s%v", j.config.lockKeyPrefix, j.config.lockKeySeparator, info.Type, j.config.lockKeySeparator, info.Id), fmt.Sprintf("已在%s@%s机器永远上锁成功%v", j.config.insideIp, j.config.outsideIp, gotime.Current().Format()))
}

@ -1,219 +0,0 @@
package gojobs
import (
"go.dtapp.net/gojobs/jobs_gorm_model"
"gorm.io/gorm"
"log"
"strings"
)
// TaskTakeId 查询单任务
func (j *JobsGorm) TaskTakeId(tx *gorm.DB, id uint) (result jobs_gorm_model.Task) {
tx.Where("id = ?", id).Take(&result)
return result
}
// TaskTake 查询单任务
func (j *JobsGorm) TaskTake(tx *gorm.DB, customId string) (result jobs_gorm_model.Task) {
tx.Where("custom_id = ?", customId).Take(&result)
return result
}
// 查询单任务
func (j *JobsGorm) taskTake(tx *gorm.DB, customId, status string) (result jobs_gorm_model.Task) {
tx.Where("custom_id = ?", customId).Where("status = ?", status).Take(&result)
return result
}
// TaskTakeIn 查询单任务 - 任务运行
func (j *JobsGorm) TaskTakeIn(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return j.taskTake(tx, customId, TASK_IN)
}
// TaskTakeSuccess 查询单任务 - 任务完成
func (j *JobsGorm) TaskTakeSuccess(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return j.taskTake(tx, customId, TASK_SUCCESS)
}
// TaskTakeError 查询单任务 - 任务异常
func (j *JobsGorm) TaskTakeError(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return j.taskTake(tx, customId, TASK_ERROR)
}
// TaskTakeTimeout 查询单任务 - 任务超时
func (j *JobsGorm) TaskTakeTimeout(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return j.taskTake(tx, customId, TASK_TIMEOUT)
}
// TaskTakeWait 查询单任务 - 任务等待
func (j *JobsGorm) TaskTakeWait(tx *gorm.DB, customId string) jobs_gorm_model.Task {
return j.taskTake(tx, customId, TASK_WAIT)
}
// TaskTypeTake 查询单任务
func (j *JobsGorm) TaskTypeTake(tx *gorm.DB, customId, Type string) (result jobs_gorm_model.Task) {
tx.Where("custom_id = ?", customId).Where("type = ?", Type).Take(&result)
return result
}
// 查询单任务
func (j *JobsGorm) taskTypeTake(tx *gorm.DB, customId, Type, status string) (result jobs_gorm_model.Task) {
tx.Where("custom_id = ?", customId).Where("type = ?", Type).Where("status = ?", status).Take(&result)
return result
}
// TaskTypeTakeIn 查询单任务 - 任务运行
func (j *JobsGorm) TaskTypeTakeIn(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return j.taskTypeTake(tx, customId, Type, TASK_IN)
}
// TaskTypeTakeSuccess 查询单任务 - 任务完成
func (j *JobsGorm) TaskTypeTakeSuccess(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return j.taskTypeTake(tx, customId, Type, TASK_SUCCESS)
}
// TaskTypeTakeError 查询单任务 - 任务异常
func (j *JobsGorm) TaskTypeTakeError(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return j.taskTypeTake(tx, customId, Type, TASK_ERROR)
}
// TaskTypeTakeTimeout 查询单任务 - 任务超时
func (j *JobsGorm) TaskTypeTakeTimeout(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return j.taskTypeTake(tx, customId, Type, TASK_TIMEOUT)
}
// TaskTypeTakeWait 查询单任务 - 任务等待
func (j *JobsGorm) TaskTypeTakeWait(tx *gorm.DB, customId, Type string) jobs_gorm_model.Task {
return j.taskTypeTake(tx, customId, Type, TASK_WAIT)
}
// TaskFindAll 查询多任务
func (j *JobsGorm) TaskFindAll(tx *gorm.DB, frequency int64) (results []jobs_gorm_model.Task) {
tx.Where("frequency = ?", frequency).Order("id asc").Find(&results)
return results
}
// 查询多任务
func (j *JobsGorm) taskFindAll(tx *gorm.DB, frequency int64, status string) (results []jobs_gorm_model.Task) {
tx.Where("frequency = ?", frequency).Where("status = ?", status).Order("id asc").Find(&results)
return results
}
// TaskFindAllIn 查询多任务 - 任务运行
func (j *JobsGorm) TaskFindAllIn(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return j.taskFindAll(tx, frequency, TASK_IN)
}
// TaskFindAllSuccess 查询多任务 - 任务完成
func (j *JobsGorm) TaskFindAllSuccess(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return j.taskFindAll(tx, frequency, TASK_SUCCESS)
}
// TaskFindAllError 查询多任务 - 任务异常
func (j *JobsGorm) TaskFindAllError(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return j.taskFindAll(tx, frequency, TASK_ERROR)
}
// TaskFindAllTimeout 查询多任务 - 任务超时
func (j *JobsGorm) TaskFindAllTimeout(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return j.taskFindAll(tx, frequency, TASK_TIMEOUT)
}
// TaskFindAllWait 查询多任务 - 任务等待
func (j *JobsGorm) TaskFindAllWait(tx *gorm.DB, frequency int64) []jobs_gorm_model.Task {
return j.taskFindAll(tx, frequency, TASK_WAIT)
}
// StartTask 任务启动
func (j *JobsGorm) StartTask(tx *gorm.DB, id uint) error {
return j.EditTask(tx, id).
Select("status", "status_desc").
Updates(jobs_gorm_model.Task{
Status: TASK_IN,
StatusDesc: "启动任务",
}).Error
}
// StartTaskCustom 任务启动自定义
func (j *JobsGorm) StartTaskCustom(tx *gorm.DB, customId string, customSequence int64) error {
return tx.Model(&jobs_gorm_model.Task{}).
Where("custom_id = ?", customId).
Where("custom_sequence = ?", customSequence).
Where("status = ?", TASK_WAIT).
Select("status", "status_desc").
Updates(jobs_gorm_model.Task{
Status: TASK_IN,
StatusDesc: "启动任务",
}).Error
}
// EditTask 任务修改
func (j *JobsGorm) EditTask(tx *gorm.DB, id uint) *gorm.DB {
return tx.Model(&jobs_gorm_model.Task{}).Where("id = ?", id)
}
// UpdateFrequency 更新任务频率
func (j *JobsGorm) UpdateFrequency(tx *gorm.DB, id uint, frequency int64) *gorm.DB {
return j.EditTask(tx, id).
Select("frequency").
Updates(jobs_gorm_model.Task{
Frequency: frequency,
})
}
func (j *JobsGorm) taskIpTake(tx *gorm.DB, taskType, ips string) (result jobs_gorm_model.TaskIp) {
tx.Where("task_type = ?", taskType).Where("ips = ?", ips).Take(&result)
return result
}
// TaskIpUpdate 更新ip
func (j *JobsGorm) TaskIpUpdate(tx *gorm.DB, taskType, ips string) *gorm.DB {
query := j.taskIpTake(tx, taskType, ips)
if query.Id != 0 {
return tx
}
updateStatus := tx.Create(&jobs_gorm_model.TaskIp{
TaskType: taskType,
Ips: ips,
})
if updateStatus.RowsAffected == 0 {
log.Println("任务更新失败:", updateStatus.Error)
}
return updateStatus
}
// TaskIpInit 实例任务ip
func (j *JobsGorm) TaskIpInit(tx *gorm.DB, ips map[string]string) bool {
if j.config.outsideIp == "" || j.config.outsideIp == "0.0.0.0" {
return false
}
tx.Where("ips = ?", j.config.outsideIp).Delete(&jobs_gorm_model.TaskIp{}) // 删除
for k, v := range ips {
if v == "" {
j.TaskIpUpdate(tx, k, j.config.outsideIp)
} else {
find := strings.Contains(v, ",")
if find == true {
// 包含
parts := strings.Split(v, ",")
for _, vv := range parts {
if vv == j.config.outsideIp {
j.TaskIpUpdate(tx, k, j.config.outsideIp)
}
}
} else {
// 不包含
if v == j.config.outsideIp {
j.TaskIpUpdate(tx, k, j.config.outsideIp)
}
}
}
}
return true
}
// TaskLogRunTake 查询任务执行日志
func (j *JobsGorm) TaskLogRunTake(tx *gorm.DB, taskId uint, runId string) (result jobs_gorm_model.TaskLogRun) {
tx.Select("id", "os", "arch", "outside_ip", "created_at").Where("task_id = ?", taskId).Where("run_id = ?", runId).Take(&result)
return result
}

@ -30,6 +30,6 @@ type Task struct {
DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间" json:"deleted_at"` // 删除时间
}
func (m *Task) TableName() string {
func (Task) TableName() string {
return "task"
}

@ -7,6 +7,6 @@ type TaskIp struct {
Ips string `gorm:"comment:任务IP" json:"ips"` // 任务IP
}
func (m *TaskIp) TableName() string {
func (TaskIp) TableName() string {
return "task_ip"
}

@ -12,6 +12,6 @@ type TaskLog struct {
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"` // 创建时间
}
func (m *TaskLog) TableName() string {
func (TaskLog) TableName() string {
return "task_log"
}

@ -17,6 +17,6 @@ type TaskLogRun struct {
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"` // 创建时间
}
func (m *TaskLogRun) TableName() string {
func (TaskLogRun) TableName() string {
return "task_log_run"
}

@ -1,38 +0,0 @@
package gojobs
import (
"context"
"github.com/go-redis/redis/v9"
"log"
)
// Publish 发布
// ctx 上下文
// channel 频道
// message 消息
func (j *JobsGorm) Publish(ctx context.Context, channel string, message interface{}) error {
publish, err := j.redisClient.Publish(ctx, channel, message).Result()
if j.config.logDebug == true {
log.Printf("[jobs.Publish] %s %s %v %s\n", channel, message, publish, err)
}
return err
}
type SubscribeResult struct {
err error
Message *redis.PubSub
}
// Subscribe 订阅
func (j *JobsGorm) Subscribe(ctx context.Context) SubscribeResult {
return SubscribeResult{
Message: j.redisClient.Subscribe(ctx, j.config.cornKeyPrefix+"_"+j.config.cornKeyCustom),
}
}
// PSubscribe 订阅,支持通配符匹配(ch_user_*)
func (j *JobsGorm) PSubscribe(ctx context.Context) SubscribeResult {
return SubscribeResult{
Message: j.redisClient.PSubscribe(ctx, j.config.cornKeyPrefix+"_"+j.config.cornKeyCustom+"_*"),
}
}

@ -0,0 +1,34 @@
package jobs_mongo_model
import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
// Task 任务
type Task struct {
Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"` // 记录编号
Status string `json:"status,omitempty" bson:"status,omitempty"` // 状态码
Params string `json:"params,omitempty" bson:"params,omitempty"` // 参数
ParamsType string `json:"params_type,omitempty" bson:"params_type,omitempty"` // 参数类型
StatusDesc string `json:"status_desc,omitempty" bson:"status_desc,omitempty"` // 状态描述
Frequency int64 `json:"frequency,omitempty" bson:"frequency,omitempty"` // 频率(秒单位)
Number int64 `json:"number,omitempty" bson:"number,omitempty"` // 当前次数
MaxNumber int64 `json:"max_number,omitempty" bson:"max_number,omitempty"` // 最大次数
RunId string `json:"run_id,omitempty" bson:"run_id,omitempty"` // 执行编号
CustomId string `json:"custom_id,omitempty" bson:"custom_id,omitempty"` // 自定义编号
CustomSequence int64 `json:"custom_sequence,omitempty" bson:"custom_sequence,omitempty"` // 自定义顺序
Type string `json:"type,omitempty" bson:"type,omitempty"` // 类型
TypeName string `json:"type_name,omitempty" bson:"type_name,omitempty"` // 类型名称
CreatedIp string `json:"created_ip,omitempty" bson:"created_ip,omitempty"` // 创建外网IP
SpecifyIp string `json:"specify_ip,omitempty" bson:"specify_ip,omitempty"` // 指定外网IP
UpdatedIp string `json:"updated_ip,omitempty" bson:"updated_ip,omitempty"` // 更新外网IP
Result string `json:"result,omitempty" bson:"result,omitempty"` // 结果
NextRunTime primitive.DateTime `json:"next_run_time,omitempty" bson:"next_run_time,omitempty"` // 下次运行时间
CreatedAt primitive.DateTime `json:"created_at,omitempty" bson:"created_at,omitempty"` // 创建时间
UpdatedAt primitive.DateTime `json:"updated_at,omitempty" bson:"updated_at,omitempty"` // 更新时间
DeletedAt primitive.DateTime `json:"deleted_at,omitempty" bson:"deleted_at,omitempty"` // 删除时间
}
func (Task) TableName() string {
return "task"
}

@ -0,0 +1,14 @@
package jobs_mongo_model
import "go.mongodb.org/mongo-driver/bson/primitive"
// TaskIp 任务Ip
type TaskIp struct {
Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"` // 记录编号
TaskType string `json:"task_type,omitempty" bson:"task_type,omitempty"` // 任务编号
Ips string `json:"ips,omitempty" bson:"ips,omitempty"` // 任务IP
}
func (TaskIp) TableName() string {
return "task_ip"
}

@ -0,0 +1,19 @@
package jobs_mongo_model
import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
// TaskLog 任务日志模型
type TaskLog struct {
Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"` // 记录编号
TaskId uint `json:"task_id,omitempty" bson:"task_id,omitempty"` // 任务编号
StatusCode int `json:"status_code,omitempty" bson:"status_code,omitempty"` // 状态码
Desc string `json:"desc,omitempty" bson:"desc,omitempty"` // 结果
Version string `json:"version,omitempty" bson:"version,omitempty"` // 版本
CreatedAt primitive.DateTime `json:"created_at,omitempty" bson:"created_at,omitempty"` // 创建时间
}
func (TaskLog) TableName() string {
return "task_log"
}

@ -0,0 +1,24 @@
package jobs_mongo_model
import (
"go.mongodb.org/mongo-driver/bson/primitive"
)
// TaskLogRun 任务执行日志模型
type TaskLogRun struct {
Id primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"` // 记录编号
TaskId uint `json:"task_id,omitempty" bson:"task_id,omitempty"` // 任务编号
RunId string `json:"run_id,omitempty" bson:"run_id,omitempty"` // 执行编号
OutsideIp string `json:"outside_ip,omitempty" bson:"outside_ip,omitempty"` // 外网ip
InsideIp string `json:"inside_ip,omitempty" bson:"inside_ip,omitempty"` // 内网ip
Os string `json:"os,omitempty" bson:"os,omitempty"` // 系统类型
Arch string `json:"arch,omitempty" bson:"arch,omitempty"` // 系统架构
Gomaxprocs int `json:"gomaxprocs,omitempty" bson:"gomaxprocs,omitempty"` // CPU核数
GoVersion string `json:"go_version,omitempty" bson:"go_version,omitempty"` // GO版本
MacAddrs string `json:"mac_addrs,omitempty" bson:"mac_addrs,omitempty"` // Mac地址
CreatedAt primitive.DateTime `json:"created_at,omitempty" bson:"created_at,omitempty"` // 创建时间
}
func (TaskLogRun) TableName() string {
return "task_log_run"
}

@ -26,6 +26,6 @@ type Task struct {
DeletedAt string `xorm:"deleted" json:"deleted_at"` // 删除时间
}
func (m *Task) TableName() string {
func (Task) TableName() string {
return "task"
}

@ -7,6 +7,6 @@ type TaskIp struct {
Ips string `json:"ips"` // 任务IP
}
func (m *TaskIp) TableName() string {
func (TaskIp) TableName() string {
return "task_ip"
}

@ -10,6 +10,6 @@ type TaskLog struct {
CreatedAt string `xorm:"created" json:"created_at"` // 创建时间
}
func (m *TaskLog) TableName() string {
func (TaskLog) TableName() string {
return "task_log"
}

@ -15,6 +15,6 @@ type TaskLogRun struct {
CreatedAt string `xorm:"created" json:"created_at"` // 创建时间
}
func (m *TaskLogRun) TableName() string {
func (TaskLogRun) TableName() string {
return "task_log_run"
}

@ -0,0 +1,24 @@
package gojobs
import (
"context"
"fmt"
"go.dtapp.net/gojobs/jobs_gorm_model"
"go.dtapp.net/gotime"
"time"
)
// Lock 上锁
func (c *Client) Lock(ctx context.Context, info jobs_gorm_model.Task, id any) (string, error) {
return c.cache.redisLockClient.Lock(ctx, fmt.Sprintf("%s%s%v%s%v", c.cache.lockKeyPrefix, c.cache.lockKeySeparator, info.Type, c.cache.lockKeySeparator, id), fmt.Sprintf("已在%s@%s机器上锁成功%v", c.config.insideIp, c.config.outsideIp, gotime.Current().Format()), time.Duration(info.Frequency)*3*time.Second)
}
// Unlock Lock 解锁
func (c *Client) Unlock(ctx context.Context, info jobs_gorm_model.Task, id any) error {
return c.cache.redisLockClient.Unlock(ctx, fmt.Sprintf("%s%s%v%s%v", c.cache.lockKeyPrefix, c.cache.lockKeySeparator, info.Type, c.cache.lockKeySeparator, id))
}
// LockForever 永远上锁
func (c *Client) LockForever(ctx context.Context, info jobs_gorm_model.Task, id any) (string, error) {
return c.cache.redisLockClient.LockForever(ctx, fmt.Sprintf("%s%s%v%s%v", c.cache.lockKeyPrefix, c.cache.lockKeySeparator, info.Type, c.cache.lockKeySeparator, id), fmt.Sprintf("已在%s@%s机器永远上锁成功%v", c.config.insideIp, c.config.outsideIp, gotime.Current().Format()))
}

@ -0,0 +1,24 @@
package gojobs
import (
"context"
"fmt"
"go.dtapp.net/gojobs/jobs_gorm_model"
"go.dtapp.net/gotime"
"time"
)
// LockId 上锁
func (c *Client) LockId(ctx context.Context, info jobs_gorm_model.Task) (string, error) {
return c.cache.redisLockClient.Lock(ctx, fmt.Sprintf("%s%s%v%s%v", c.cache.lockKeyPrefix, c.cache.lockKeySeparator, info.Type, c.cache.lockKeySeparator, info.Id), fmt.Sprintf("已在%s@%s机器上锁成功%v", c.config.insideIp, c.config.outsideIp, gotime.Current().Format()), time.Duration(info.Frequency)*3*time.Second)
}
// UnlockId Lock 解锁
func (c *Client) UnlockId(ctx context.Context, info jobs_gorm_model.Task) error {
return c.cache.redisLockClient.Unlock(ctx, fmt.Sprintf("%s%s%v%s%v", c.cache.lockKeyPrefix, c.cache.lockKeySeparator, info.Type, c.cache.lockKeySeparator, info.Id))
}
// LockForeverId 永远上锁
func (c *Client) LockForeverId(ctx context.Context, info jobs_gorm_model.Task) (string, error) {
return c.cache.redisLockClient.LockForever(ctx, fmt.Sprintf("%s%s%v%s%v", c.cache.lockKeyPrefix, c.cache.lockKeySeparator, info.Type, c.cache.lockKeySeparator, info.Id), fmt.Sprintf("已在%s@%s机器永远上锁成功%v", c.config.insideIp, c.config.outsideIp, gotime.Current().Format()))
}

@ -0,0 +1,140 @@
package gojobs
import (
"context"
"go.dtapp.net/gojobs/jobs_gorm_model"
"go.dtapp.net/gojobs/jobs_mongo_model"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
)
// 创建模型
func (c *Client) autoMigrateTask() {
log.Println(c.db.gormClient.Db.AutoMigrate(&jobs_gorm_model.Task{}))
}
// 创建模型
func (c *Client) autoMigrateTaskIp() {
log.Println(c.db.gormClient.Db.AutoMigrate(&jobs_gorm_model.TaskIp{}))
}
// 创建模型
func (c *Client) autoMigrateTaskLog() {
log.Println(c.db.gormClient.Db.AutoMigrate(&jobs_gorm_model.TaskLog{}))
}
// 创建模型
func (c *Client) autoMigrateTaskLogRun() {
log.Println(c.db.gormClient.Db.AutoMigrate(&jobs_gorm_model.TaskLogRun{}))
}
// 创建时间序列集合
func (c *Client) mongoCreateCollectionTask(ctx context.Context) {
var commandResult bson.M
commandErr := c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).RunCommand(ctx, bson.D{{
"listCollections", 1,
}}).Decode(&commandResult)
if commandErr != nil {
log.Println("检查时间序列集合:", commandErr)
} else {
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).CreateCollection(ctx, jobs_mongo_model.Task{}.TableName(), options.CreateCollection().SetTimeSeriesOptions(options.TimeSeries().SetTimeField("created_at"))))
}
}
// 创建索引
func (c *Client) mongoCreateIndexesTask(ctx context.Context) {
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.Task{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"status", 1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.Task{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"frequency", 1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.Task{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"custom_id", 1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.Task{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"type", 1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.Task{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"created_ip", 1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.Task{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"specify_ip", 1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.Task{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"updated_ip", 1},
}}))
}
// 创建索引
func (c *Client) mongoCreateIndexesTaskIp(ctx context.Context) {
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskIp{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"task_type", 1},
}}))
}
// 创建时间序列集合
func (c *Client) mongoCreateCollectionTaskLog(ctx context.Context) {
var commandResult bson.M
commandErr := c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).RunCommand(ctx, bson.D{{
"listCollections", 1,
}}).Decode(&commandResult)
if commandErr != nil {
log.Println("检查时间序列集合:", commandErr)
} else {
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).CreateCollection(ctx, jobs_mongo_model.TaskLog{}.TableName(), options.CreateCollection().SetTimeSeriesOptions(options.TimeSeries().SetTimeField("created_at"))))
}
}
// 创建索引
func (c *Client) mongoCreateIndexesTaskLog(ctx context.Context) {
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"task_id", -1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"status_code", -1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"version", -1},
}}))
}
// 创建时间序列集合
func (c *Client) mongoCreateCollectionTaskLogRun(ctx context.Context) {
var commandResult bson.M
commandErr := c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).RunCommand(ctx, bson.D{{
"listCollections", 1,
}}).Decode(&commandResult)
if commandErr != nil {
log.Println("检查时间序列集合:", commandErr)
} else {
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).CreateCollection(ctx, jobs_mongo_model.TaskLogRun{}.TableName(), options.CreateCollection().SetTimeSeriesOptions(options.TimeSeries().SetTimeField("created_at"))))
}
}
// 创建索引
func (c *Client) mongoCreateIndexesTaskLogRun(ctx context.Context) {
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"task_id", -1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"run_id", -1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"outside_ip", -1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"inside_ip", -1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"os", -1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"arch", -1},
}}))
log.Println(c.db.mongoClient.Db.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).Indexes().CreateOne(ctx, mongo.IndexModel{Keys: bson.D{
{"go_version", -1},
}}))
}

@ -1,221 +0,0 @@
// 版本
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v3.19.4
// source: pb/basics.proto
// 包名
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 请求消息
type BasicsRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *BasicsRequest) Reset() {
*x = BasicsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pb_basics_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BasicsRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BasicsRequest) ProtoMessage() {}
func (x *BasicsRequest) ProtoReflect() protoreflect.Message {
mi := &file_pb_basics_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BasicsRequest.ProtoReflect.Descriptor instead.
func (*BasicsRequest) Descriptor() ([]byte, []int) {
return file_pb_basics_proto_rawDescGZIP(), []int{0}
}
func (x *BasicsRequest) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
// 响应消息
type BasicsResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *BasicsResponse) Reset() {
*x = BasicsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pb_basics_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *BasicsResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BasicsResponse) ProtoMessage() {}
func (x *BasicsResponse) ProtoReflect() protoreflect.Message {
mi := &file_pb_basics_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BasicsResponse.ProtoReflect.Descriptor instead.
func (*BasicsResponse) Descriptor() ([]byte, []int) {
return file_pb_basics_proto_rawDescGZIP(), []int{1}
}
func (x *BasicsResponse) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_pb_basics_proto protoreflect.FileDescriptor
var file_pb_basics_proto_rawDesc = []byte{
0x0a, 0x0f, 0x70, 0x62, 0x2f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x29, 0x0a, 0x0d, 0x42, 0x61, 0x73, 0x69, 0x63, 0x73, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x22, 0x2a, 0x0a, 0x0e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x6a, 0x0a, 0x06,
0x42, 0x61, 0x73, 0x69, 0x63, 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x11,
0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x12,
0x11, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70,
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pb_basics_proto_rawDescOnce sync.Once
file_pb_basics_proto_rawDescData = file_pb_basics_proto_rawDesc
)
func file_pb_basics_proto_rawDescGZIP() []byte {
file_pb_basics_proto_rawDescOnce.Do(func() {
file_pb_basics_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_basics_proto_rawDescData)
})
return file_pb_basics_proto_rawDescData
}
var file_pb_basics_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_pb_basics_proto_goTypes = []interface{}{
(*BasicsRequest)(nil), // 0: pb.BasicsRequest
(*BasicsResponse)(nil), // 1: pb.BasicsResponse
}
var file_pb_basics_proto_depIdxs = []int32{
0, // 0: pb.Basics.Ping:input_type -> pb.BasicsRequest
0, // 1: pb.Basics.Pong:input_type -> pb.BasicsRequest
1, // 2: pb.Basics.Ping:output_type -> pb.BasicsResponse
1, // 3: pb.Basics.Pong:output_type -> pb.BasicsResponse
2, // [2:4] is the sub-list for method output_type
0, // [0:2] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_pb_basics_proto_init() }
func file_pb_basics_proto_init() {
if File_pb_basics_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_pb_basics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BasicsRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pb_basics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BasicsResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pb_basics_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_pb_basics_proto_goTypes,
DependencyIndexes: file_pb_basics_proto_depIdxs,
MessageInfos: file_pb_basics_proto_msgTypes,
}.Build()
File_pb_basics_proto = out.File
file_pb_basics_proto_rawDesc = nil
file_pb_basics_proto_goTypes = nil
file_pb_basics_proto_depIdxs = nil
}

@ -1,25 +0,0 @@
//
syntax = "proto3";
//
package pb;
//
option go_package = "../pb";
//
service Basics{
//
rpc Ping(BasicsRequest) returns (BasicsResponse){};
//
rpc Pong(BasicsRequest) returns (BasicsResponse){};
}
//
message BasicsRequest {
string message = 1;
}
//
message BasicsResponse {
string message = 1;
}

@ -1,145 +0,0 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.19.4
// source: pb/basics.proto
package pb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// BasicsClient is the client API for Basics service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type BasicsClient interface {
// 心跳
Ping(ctx context.Context, in *BasicsRequest, opts ...grpc.CallOption) (*BasicsResponse, error)
// 心跳
Pong(ctx context.Context, in *BasicsRequest, opts ...grpc.CallOption) (*BasicsResponse, error)
}
type basicsClient struct {
cc grpc.ClientConnInterface
}
func NewBasicsClient(cc grpc.ClientConnInterface) BasicsClient {
return &basicsClient{cc}
}
func (c *basicsClient) Ping(ctx context.Context, in *BasicsRequest, opts ...grpc.CallOption) (*BasicsResponse, error) {
out := new(BasicsResponse)
err := c.cc.Invoke(ctx, "/pb.Basics/Ping", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *basicsClient) Pong(ctx context.Context, in *BasicsRequest, opts ...grpc.CallOption) (*BasicsResponse, error) {
out := new(BasicsResponse)
err := c.cc.Invoke(ctx, "/pb.Basics/Pong", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// BasicsServer is the server API for Basics service.
// All implementations must embed UnimplementedBasicsServer
// for forward compatibility
type BasicsServer interface {
// 心跳
Ping(context.Context, *BasicsRequest) (*BasicsResponse, error)
// 心跳
Pong(context.Context, *BasicsRequest) (*BasicsResponse, error)
mustEmbedUnimplementedBasicsServer()
}
// UnimplementedBasicsServer must be embedded to have forward compatible implementations.
type UnimplementedBasicsServer struct {
}
func (UnimplementedBasicsServer) Ping(context.Context, *BasicsRequest) (*BasicsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented")
}
func (UnimplementedBasicsServer) Pong(context.Context, *BasicsRequest) (*BasicsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Pong not implemented")
}
func (UnimplementedBasicsServer) mustEmbedUnimplementedBasicsServer() {}
// UnsafeBasicsServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to BasicsServer will
// result in compilation errors.
type UnsafeBasicsServer interface {
mustEmbedUnimplementedBasicsServer()
}
func RegisterBasicsServer(s grpc.ServiceRegistrar, srv BasicsServer) {
s.RegisterService(&Basics_ServiceDesc, srv)
}
func _Basics_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BasicsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BasicsServer).Ping(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/pb.Basics/Ping",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BasicsServer).Ping(ctx, req.(*BasicsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Basics_Pong_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BasicsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BasicsServer).Pong(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/pb.Basics/Pong",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BasicsServer).Pong(ctx, req.(*BasicsRequest))
}
return interceptor(ctx, in, info, handler)
}
// Basics_ServiceDesc is the grpc.ServiceDesc for Basics service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Basics_ServiceDesc = grpc.ServiceDesc{
ServiceName: "pb.Basics",
HandlerType: (*BasicsServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Ping",
Handler: _Basics_Ping_Handler,
},
{
MethodName: "Pong",
Handler: _Basics_Pong_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "pb/basics.proto",
}

@ -1,440 +0,0 @@
// 版本
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v3.19.4
// source: pb/pubsub.proto
// 包名
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 请求消息
type PublishRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"`
Ip string `protobuf:"bytes,4,opt,name=ip,proto3" json:"ip,omitempty"`
}
func (x *PublishRequest) Reset() {
*x = PublishRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pb_pubsub_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PublishRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PublishRequest) ProtoMessage() {}
func (x *PublishRequest) ProtoReflect() protoreflect.Message {
mi := &file_pb_pubsub_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PublishRequest.ProtoReflect.Descriptor instead.
func (*PublishRequest) Descriptor() ([]byte, []int) {
return file_pb_pubsub_proto_rawDescGZIP(), []int{0}
}
func (x *PublishRequest) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *PublishRequest) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
func (x *PublishRequest) GetMethod() string {
if x != nil {
return x.Method
}
return ""
}
func (x *PublishRequest) GetIp() string {
if x != nil {
return x.Ip
}
return ""
}
// 响应消息
type PublishResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"`
}
func (x *PublishResponse) Reset() {
*x = PublishResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pb_pubsub_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PublishResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PublishResponse) ProtoMessage() {}
func (x *PublishResponse) ProtoReflect() protoreflect.Message {
mi := &file_pb_pubsub_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PublishResponse.ProtoReflect.Descriptor instead.
func (*PublishResponse) Descriptor() ([]byte, []int) {
return file_pb_pubsub_proto_rawDescGZIP(), []int{1}
}
func (x *PublishResponse) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *PublishResponse) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
func (x *PublishResponse) GetIp() string {
if x != nil {
return x.Ip
}
return ""
}
// 请求消息
type SubscribeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"`
Ip string `protobuf:"bytes,4,opt,name=ip,proto3" json:"ip,omitempty"`
}
func (x *SubscribeRequest) Reset() {
*x = SubscribeRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pb_pubsub_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SubscribeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SubscribeRequest) ProtoMessage() {}
func (x *SubscribeRequest) ProtoReflect() protoreflect.Message {
mi := &file_pb_pubsub_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SubscribeRequest.ProtoReflect.Descriptor instead.
func (*SubscribeRequest) Descriptor() ([]byte, []int) {
return file_pb_pubsub_proto_rawDescGZIP(), []int{2}
}
func (x *SubscribeRequest) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *SubscribeRequest) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
func (x *SubscribeRequest) GetMethod() string {
if x != nil {
return x.Method
}
return ""
}
func (x *SubscribeRequest) GetIp() string {
if x != nil {
return x.Ip
}
return ""
}
// 响应消息
type SubscribeResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"`
}
func (x *SubscribeResponse) Reset() {
*x = SubscribeResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pb_pubsub_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SubscribeResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SubscribeResponse) ProtoMessage() {}
func (x *SubscribeResponse) ProtoReflect() protoreflect.Message {
mi := &file_pb_pubsub_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SubscribeResponse.ProtoReflect.Descriptor instead.
func (*SubscribeResponse) Descriptor() ([]byte, []int) {
return file_pb_pubsub_proto_rawDescGZIP(), []int{3}
}
func (x *SubscribeResponse) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *SubscribeResponse) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
func (x *SubscribeResponse) GetMethod() string {
if x != nil {
return x.Method
}
return ""
}
var File_pb_pubsub_proto protoreflect.FileDescriptor
var file_pb_pubsub_proto_rawDesc = []byte{
0x0a, 0x0f, 0x70, 0x62, 0x2f, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x5e, 0x0a, 0x0e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a,
0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d,
0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28,
0x09, 0x52, 0x02, 0x69, 0x70, 0x22, 0x47, 0x0a, 0x0f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e,
0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x22, 0x60,
0x0a, 0x10, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68,
0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70,
0x22, 0x51, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d,
0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74,
0x68, 0x6f, 0x64, 0x32, 0x78, 0x0a, 0x06, 0x50, 0x75, 0x62, 0x53, 0x75, 0x62, 0x12, 0x32, 0x0a,
0x07, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x12, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x75,
0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x70,
0x62, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3a, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x14,
0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
0x69, 0x62, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x07, 0x5a,
0x05, 0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pb_pubsub_proto_rawDescOnce sync.Once
file_pb_pubsub_proto_rawDescData = file_pb_pubsub_proto_rawDesc
)
func file_pb_pubsub_proto_rawDescGZIP() []byte {
file_pb_pubsub_proto_rawDescOnce.Do(func() {
file_pb_pubsub_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_pubsub_proto_rawDescData)
})
return file_pb_pubsub_proto_rawDescData
}
var file_pb_pubsub_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_pb_pubsub_proto_goTypes = []interface{}{
(*PublishRequest)(nil), // 0: pb.PublishRequest
(*PublishResponse)(nil), // 1: pb.PublishResponse
(*SubscribeRequest)(nil), // 2: pb.SubscribeRequest
(*SubscribeResponse)(nil), // 3: pb.SubscribeResponse
}
var file_pb_pubsub_proto_depIdxs = []int32{
0, // 0: pb.PubSub.Publish:input_type -> pb.PublishRequest
2, // 1: pb.PubSub.Subscribe:input_type -> pb.SubscribeRequest
1, // 2: pb.PubSub.Publish:output_type -> pb.PublishResponse
3, // 3: pb.PubSub.Subscribe:output_type -> pb.SubscribeResponse
2, // [2:4] is the sub-list for method output_type
0, // [0:2] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_pb_pubsub_proto_init() }
func file_pb_pubsub_proto_init() {
if File_pb_pubsub_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_pb_pubsub_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PublishRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pb_pubsub_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PublishResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pb_pubsub_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SubscribeRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pb_pubsub_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SubscribeResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pb_pubsub_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_pb_pubsub_proto_goTypes,
DependencyIndexes: file_pb_pubsub_proto_depIdxs,
MessageInfos: file_pb_pubsub_proto_msgTypes,
}.Build()
File_pb_pubsub_proto = out.File
file_pb_pubsub_proto_rawDesc = nil
file_pb_pubsub_proto_goTypes = nil
file_pb_pubsub_proto_depIdxs = nil
}

@ -1,46 +0,0 @@
//
syntax = "proto3";
//
package pb;
//
option go_package = "../pb";
//
service PubSub {
// []
rpc Publish (PublishRequest) returns (PublishResponse);
// []
rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse);
}
//
message PublishRequest {
string id = 1;
string value = 2;
string method = 3;
string ip = 4;
}
//
message PublishResponse {
string id = 1;
string value = 2;
string ip = 3;
}
//
message SubscribeRequest {
string id = 1;
string value = 2;
string method = 3;
string ip = 4;
}
//
message SubscribeResponse {
string id = 1;
string value = 2;
string method = 3;
}

@ -1,77 +0,0 @@
package pb
import (
"context"
"go.dtapp.net/gojobs/pubsub"
"log"
"strings"
"time"
)
type PubSubServerService struct {
pub *pubsub.Publisher
UnimplementedPubSubServer
}
func NewPubSubServerService() *PubSubServerService {
return &PubSubServerService{
// 新建一个Publisher对象
pub: pubsub.NewPublisher(time.Millisecond*100, 10),
}
}
// Publish 实现发布方法
func (p *PubSubServerService) Publish(ctx context.Context, req *PublishRequest) (*PublishResponse, error) {
log.Printf("[服务中转]{发布}编号:%s 类型:%s ip地址%s\n", req.GetId(), req.GetValue(), req.GetIp())
// 发布消息
p.pub.Publish(req.GetValue())
return &PublishResponse{
Id: req.GetId(),
Value: req.GetValue(),
Ip: req.GetIp(),
}, nil
}
// Subscribe 实现订阅方法
func (p *PubSubServerService) Subscribe(req *SubscribeRequest, stream PubSub_SubscribeServer) error {
// SubscribeTopic 增加一个使用函数过滤器的订阅者
// func(v interface{}) 定义函数过滤的规则
// SubscribeTopic 返回一个chan interface{}
ch := p.pub.SubscribeTopic(func(v interface{}) bool {
log.Printf("[服务中转]{订阅}主题:%v\n", v)
// 接收数据是string并且key是以arg为前缀的
if key, ok := v.(string); ok {
if strings.HasPrefix(key, req.GetValue()) {
return true
}
}
return false
})
log.Printf("[服务中转]{订阅}编号:%s 类型:%s 方法:%s ip地址%s\n", req.GetId(), req.GetValue(), req.GetMethod(), req.GetIp())
log.Println("[服务中转]{订阅}工作线:", ch)
log.Println("[服务中转]{订阅}当前工作线数量:", p.pub.Len())
// 服务器遍历chan并将其中信息发送给订阅客户端
for v := range ch {
log.Println("[服务中转]{订阅}for ch", ch)
log.Println("[服务中转]{订阅}for v", v)
err := stream.Send(&SubscribeResponse{
Id: req.GetId(),
Value: req.GetValue(),
Method: req.GetMethod(),
})
if err != nil {
log.Println("[服务中转]{订阅}任务分配失败 ", err.Error())
return err
}
}
return nil
}

@ -1,173 +0,0 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.19.4
// source: pb/pubsub.proto
package pb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// PubSubClient is the client API for PubSub service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type PubSubClient interface {
// [发布] 消息
Publish(ctx context.Context, in *PublishRequest, opts ...grpc.CallOption) (*PublishResponse, error)
// [订阅] 消息
Subscribe(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (PubSub_SubscribeClient, error)
}
type pubSubClient struct {
cc grpc.ClientConnInterface
}
func NewPubSubClient(cc grpc.ClientConnInterface) PubSubClient {
return &pubSubClient{cc}
}
func (c *pubSubClient) Publish(ctx context.Context, in *PublishRequest, opts ...grpc.CallOption) (*PublishResponse, error) {
out := new(PublishResponse)
err := c.cc.Invoke(ctx, "/pb.PubSub/Publish", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *pubSubClient) Subscribe(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (PubSub_SubscribeClient, error) {
stream, err := c.cc.NewStream(ctx, &PubSub_ServiceDesc.Streams[0], "/pb.PubSub/Subscribe", opts...)
if err != nil {
return nil, err
}
x := &pubSubSubscribeClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type PubSub_SubscribeClient interface {
Recv() (*SubscribeResponse, error)
grpc.ClientStream
}
type pubSubSubscribeClient struct {
grpc.ClientStream
}
func (x *pubSubSubscribeClient) Recv() (*SubscribeResponse, error) {
m := new(SubscribeResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// PubSubServer is the server API for PubSub service.
// All implementations must embed UnimplementedPubSubServer
// for forward compatibility
type PubSubServer interface {
// [发布] 消息
Publish(context.Context, *PublishRequest) (*PublishResponse, error)
// [订阅] 消息
Subscribe(*SubscribeRequest, PubSub_SubscribeServer) error
mustEmbedUnimplementedPubSubServer()
}
// UnimplementedPubSubServer must be embedded to have forward compatible implementations.
type UnimplementedPubSubServer struct {
}
func (UnimplementedPubSubServer) Publish(context.Context, *PublishRequest) (*PublishResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Publish not implemented")
}
func (UnimplementedPubSubServer) Subscribe(*SubscribeRequest, PubSub_SubscribeServer) error {
return status.Errorf(codes.Unimplemented, "method Subscribe not implemented")
}
func (UnimplementedPubSubServer) mustEmbedUnimplementedPubSubServer() {}
// UnsafePubSubServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to PubSubServer will
// result in compilation errors.
type UnsafePubSubServer interface {
mustEmbedUnimplementedPubSubServer()
}
func RegisterPubSubServer(s grpc.ServiceRegistrar, srv PubSubServer) {
s.RegisterService(&PubSub_ServiceDesc, srv)
}
func _PubSub_Publish_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PublishRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(PubSubServer).Publish(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/pb.PubSub/Publish",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(PubSubServer).Publish(ctx, req.(*PublishRequest))
}
return interceptor(ctx, in, info, handler)
}
func _PubSub_Subscribe_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(SubscribeRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(PubSubServer).Subscribe(m, &pubSubSubscribeServer{stream})
}
type PubSub_SubscribeServer interface {
Send(*SubscribeResponse) error
grpc.ServerStream
}
type pubSubSubscribeServer struct {
grpc.ServerStream
}
func (x *pubSubSubscribeServer) Send(m *SubscribeResponse) error {
return x.ServerStream.SendMsg(m)
}
// PubSub_ServiceDesc is the grpc.ServiceDesc for PubSub service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var PubSub_ServiceDesc = grpc.ServiceDesc{
ServiceName: "pb.PubSub",
HandlerType: (*PubSubServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Publish",
Handler: _PubSub_Publish_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "Subscribe",
Handler: _PubSub_Subscribe_Handler,
ServerStreams: true,
},
},
Metadata: "pb/pubsub.proto",
}

@ -1,234 +0,0 @@
// 版本
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v3.19.4
// source: pb/task.proto
// 包名
package pb
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 请求消息
type TaskRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *TaskRequest) Reset() {
*x = TaskRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pb_task_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *TaskRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TaskRequest) ProtoMessage() {}
func (x *TaskRequest) ProtoReflect() protoreflect.Message {
mi := &file_pb_task_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TaskRequest.ProtoReflect.Descriptor instead.
func (*TaskRequest) Descriptor() ([]byte, []int) {
return file_pb_task_proto_rawDescGZIP(), []int{0}
}
func (x *TaskRequest) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
// 响应消息
type TaskResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *TaskResponse) Reset() {
*x = TaskResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pb_task_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *TaskResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TaskResponse) ProtoMessage() {}
func (x *TaskResponse) ProtoReflect() protoreflect.Message {
mi := &file_pb_task_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TaskResponse.ProtoReflect.Descriptor instead.
func (*TaskResponse) Descriptor() ([]byte, []int) {
return file_pb_task_proto_rawDescGZIP(), []int{1}
}
func (x *TaskResponse) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_pb_task_proto protoreflect.FileDescriptor
var file_pb_task_proto_rawDesc = []byte{
0x0a, 0x0d, 0x70, 0x62, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x02, 0x70, 0x62, 0x22, 0x27, 0x0a, 0x0b, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x28, 0x0a, 0x0c,
0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0xfb, 0x01, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b, 0x12,
0x30, 0x0a, 0x09, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0f, 0x2e, 0x70,
0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e,
0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x3c, 0x0a, 0x13, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x61,
0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x54,
0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12,
0x3c, 0x0a, 0x13, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69,
0x6e, 0x67, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x62, 0x2e, 0x54, 0x61, 0x73,
0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x45, 0x0a,
0x1a, 0x42, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0f, 0x2e, 0x70, 0x62,
0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70,
0x62, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x28, 0x01, 0x30, 0x01, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pb_task_proto_rawDescOnce sync.Once
file_pb_task_proto_rawDescData = file_pb_task_proto_rawDesc
)
func file_pb_task_proto_rawDescGZIP() []byte {
file_pb_task_proto_rawDescOnce.Do(func() {
file_pb_task_proto_rawDescData = protoimpl.X.CompressGZIP(file_pb_task_proto_rawDescData)
})
return file_pb_task_proto_rawDescData
}
var file_pb_task_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_pb_task_proto_goTypes = []interface{}{
(*TaskRequest)(nil), // 0: pb.TaskRequest
(*TaskResponse)(nil), // 1: pb.TaskResponse
}
var file_pb_task_proto_depIdxs = []int32{
0, // 0: pb.Task.UnaryTask:input_type -> pb.TaskRequest
0, // 1: pb.Task.ServerStreamingTask:input_type -> pb.TaskRequest
0, // 2: pb.Task.ClientStreamingTask:input_type -> pb.TaskRequest
0, // 3: pb.Task.BidirectionalStreamingTask:input_type -> pb.TaskRequest
1, // 4: pb.Task.UnaryTask:output_type -> pb.TaskResponse
1, // 5: pb.Task.ServerStreamingTask:output_type -> pb.TaskResponse
1, // 6: pb.Task.ClientStreamingTask:output_type -> pb.TaskResponse
1, // 7: pb.Task.BidirectionalStreamingTask:output_type -> pb.TaskResponse
4, // [4:8] is the sub-list for method output_type
0, // [0:4] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_pb_task_proto_init() }
func file_pb_task_proto_init() {
if File_pb_task_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_pb_task_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TaskRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pb_task_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TaskResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_pb_task_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_pb_task_proto_goTypes,
DependencyIndexes: file_pb_task_proto_depIdxs,
MessageInfos: file_pb_task_proto_msgTypes,
}.Build()
File_pb_task_proto = out.File
file_pb_task_proto_rawDesc = nil
file_pb_task_proto_goTypes = nil
file_pb_task_proto_depIdxs = nil
}

@ -1,30 +0,0 @@
//
syntax = "proto3";
//
package pb;
//
option go_package = "../pb";
//
service Task{
//
rpc UnaryTask(TaskRequest) returns (TaskResponse){};
//
rpc ServerStreamingTask(TaskRequest) returns (stream TaskResponse){};
//
rpc ClientStreamingTask(stream TaskRequest) returns (TaskResponse){};
//
rpc BidirectionalStreamingTask(stream TaskRequest) returns (stream TaskResponse){};
}
//
message TaskRequest {
string message = 1;
}
//
message TaskResponse {
string message = 1;
}

@ -1,315 +0,0 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.19.4
// source: pb/task.proto
package pb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// TaskClient is the client API for Task service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type TaskClient interface {
// 普通一元方法
UnaryTask(ctx context.Context, in *TaskRequest, opts ...grpc.CallOption) (*TaskResponse, error)
// 服务端推送流
ServerStreamingTask(ctx context.Context, in *TaskRequest, opts ...grpc.CallOption) (Task_ServerStreamingTaskClient, error)
// 客户端推送流
ClientStreamingTask(ctx context.Context, opts ...grpc.CallOption) (Task_ClientStreamingTaskClient, error)
// 双向推送流
BidirectionalStreamingTask(ctx context.Context, opts ...grpc.CallOption) (Task_BidirectionalStreamingTaskClient, error)
}
type taskClient struct {
cc grpc.ClientConnInterface
}
func NewTaskClient(cc grpc.ClientConnInterface) TaskClient {
return &taskClient{cc}
}
func (c *taskClient) UnaryTask(ctx context.Context, in *TaskRequest, opts ...grpc.CallOption) (*TaskResponse, error) {
out := new(TaskResponse)
err := c.cc.Invoke(ctx, "/pb.Task/UnaryTask", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *taskClient) ServerStreamingTask(ctx context.Context, in *TaskRequest, opts ...grpc.CallOption) (Task_ServerStreamingTaskClient, error) {
stream, err := c.cc.NewStream(ctx, &Task_ServiceDesc.Streams[0], "/pb.Task/ServerStreamingTask", opts...)
if err != nil {
return nil, err
}
x := &taskServerStreamingTaskClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type Task_ServerStreamingTaskClient interface {
Recv() (*TaskResponse, error)
grpc.ClientStream
}
type taskServerStreamingTaskClient struct {
grpc.ClientStream
}
func (x *taskServerStreamingTaskClient) Recv() (*TaskResponse, error) {
m := new(TaskResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *taskClient) ClientStreamingTask(ctx context.Context, opts ...grpc.CallOption) (Task_ClientStreamingTaskClient, error) {
stream, err := c.cc.NewStream(ctx, &Task_ServiceDesc.Streams[1], "/pb.Task/ClientStreamingTask", opts...)
if err != nil {
return nil, err
}
x := &taskClientStreamingTaskClient{stream}
return x, nil
}
type Task_ClientStreamingTaskClient interface {
Send(*TaskRequest) error
CloseAndRecv() (*TaskResponse, error)
grpc.ClientStream
}
type taskClientStreamingTaskClient struct {
grpc.ClientStream
}
func (x *taskClientStreamingTaskClient) Send(m *TaskRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *taskClientStreamingTaskClient) CloseAndRecv() (*TaskResponse, error) {
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
m := new(TaskResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *taskClient) BidirectionalStreamingTask(ctx context.Context, opts ...grpc.CallOption) (Task_BidirectionalStreamingTaskClient, error) {
stream, err := c.cc.NewStream(ctx, &Task_ServiceDesc.Streams[2], "/pb.Task/BidirectionalStreamingTask", opts...)
if err != nil {
return nil, err
}
x := &taskBidirectionalStreamingTaskClient{stream}
return x, nil
}
type Task_BidirectionalStreamingTaskClient interface {
Send(*TaskRequest) error
Recv() (*TaskResponse, error)
grpc.ClientStream
}
type taskBidirectionalStreamingTaskClient struct {
grpc.ClientStream
}
func (x *taskBidirectionalStreamingTaskClient) Send(m *TaskRequest) error {
return x.ClientStream.SendMsg(m)
}
func (x *taskBidirectionalStreamingTaskClient) Recv() (*TaskResponse, error) {
m := new(TaskResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// TaskServer is the server API for Task service.
// All implementations must embed UnimplementedTaskServer
// for forward compatibility
type TaskServer interface {
// 普通一元方法
UnaryTask(context.Context, *TaskRequest) (*TaskResponse, error)
// 服务端推送流
ServerStreamingTask(*TaskRequest, Task_ServerStreamingTaskServer) error
// 客户端推送流
ClientStreamingTask(Task_ClientStreamingTaskServer) error
// 双向推送流
BidirectionalStreamingTask(Task_BidirectionalStreamingTaskServer) error
mustEmbedUnimplementedTaskServer()
}
// UnimplementedTaskServer must be embedded to have forward compatible implementations.
type UnimplementedTaskServer struct {
}
func (UnimplementedTaskServer) UnaryTask(context.Context, *TaskRequest) (*TaskResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnaryTask not implemented")
}
func (UnimplementedTaskServer) ServerStreamingTask(*TaskRequest, Task_ServerStreamingTaskServer) error {
return status.Errorf(codes.Unimplemented, "method ServerStreamingTask not implemented")
}
func (UnimplementedTaskServer) ClientStreamingTask(Task_ClientStreamingTaskServer) error {
return status.Errorf(codes.Unimplemented, "method ClientStreamingTask not implemented")
}
func (UnimplementedTaskServer) BidirectionalStreamingTask(Task_BidirectionalStreamingTaskServer) error {
return status.Errorf(codes.Unimplemented, "method BidirectionalStreamingTask not implemented")
}
func (UnimplementedTaskServer) mustEmbedUnimplementedTaskServer() {}
// UnsafeTaskServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to TaskServer will
// result in compilation errors.
type UnsafeTaskServer interface {
mustEmbedUnimplementedTaskServer()
}
func RegisterTaskServer(s grpc.ServiceRegistrar, srv TaskServer) {
s.RegisterService(&Task_ServiceDesc, srv)
}
func _Task_UnaryTask_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(TaskRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TaskServer).UnaryTask(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/pb.Task/UnaryTask",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TaskServer).UnaryTask(ctx, req.(*TaskRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Task_ServerStreamingTask_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(TaskRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(TaskServer).ServerStreamingTask(m, &taskServerStreamingTaskServer{stream})
}
type Task_ServerStreamingTaskServer interface {
Send(*TaskResponse) error
grpc.ServerStream
}
type taskServerStreamingTaskServer struct {
grpc.ServerStream
}
func (x *taskServerStreamingTaskServer) Send(m *TaskResponse) error {
return x.ServerStream.SendMsg(m)
}
func _Task_ClientStreamingTask_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(TaskServer).ClientStreamingTask(&taskClientStreamingTaskServer{stream})
}
type Task_ClientStreamingTaskServer interface {
SendAndClose(*TaskResponse) error
Recv() (*TaskRequest, error)
grpc.ServerStream
}
type taskClientStreamingTaskServer struct {
grpc.ServerStream
}
func (x *taskClientStreamingTaskServer) SendAndClose(m *TaskResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *taskClientStreamingTaskServer) Recv() (*TaskRequest, error) {
m := new(TaskRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func _Task_BidirectionalStreamingTask_Handler(srv interface{}, stream grpc.ServerStream) error {
return srv.(TaskServer).BidirectionalStreamingTask(&taskBidirectionalStreamingTaskServer{stream})
}
type Task_BidirectionalStreamingTaskServer interface {
Send(*TaskResponse) error
Recv() (*TaskRequest, error)
grpc.ServerStream
}
type taskBidirectionalStreamingTaskServer struct {
grpc.ServerStream
}
func (x *taskBidirectionalStreamingTaskServer) Send(m *TaskResponse) error {
return x.ServerStream.SendMsg(m)
}
func (x *taskBidirectionalStreamingTaskServer) Recv() (*TaskRequest, error) {
m := new(TaskRequest)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// Task_ServiceDesc is the grpc.ServiceDesc for Task service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Task_ServiceDesc = grpc.ServiceDesc{
ServiceName: "pb.Task",
HandlerType: (*TaskServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "UnaryTask",
Handler: _Task_UnaryTask_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "ServerStreamingTask",
Handler: _Task_ServerStreamingTask_Handler,
ServerStreams: true,
},
{
StreamName: "ClientStreamingTask",
Handler: _Task_ClientStreamingTask_Handler,
ClientStreams: true,
},
{
StreamName: "BidirectionalStreamingTask",
Handler: _Task_BidirectionalStreamingTask_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "pb/task.proto",
}

@ -1,125 +0,0 @@
package pubsub
import (
"sync"
"time"
)
// 等待组放在共享内存池中减少GC
var wgPool = sync.Pool{New: func() interface{} { return new(sync.WaitGroup) }}
// NewPublisher
// 第一个参数控制发布时最大阻塞时间
// 第二个参数是缓冲区大小控制每个订阅者的chan缓冲区大小
func NewPublisher(publishTimeout time.Duration, buffer int) *Publisher {
return &Publisher{
buffer: buffer,
timeout: publishTimeout,
subscribers: make(map[subscriber]topicFunc),
}
}
type subscriber chan interface{}
type topicFunc func(v interface{}) bool
type Publisher struct {
m sync.RWMutex // 控制订阅者map并发读写安全
buffer int // 每个订阅者chan缓冲区大小
timeout time.Duration // 发布阻塞超时时间
subscribers map[subscriber]topicFunc
}
// Len 返回订阅者数量
func (p *Publisher) Len() int {
p.m.RLock()
i := len(p.subscribers)
p.m.RUnlock()
return i
}
// Subscribe 无Topic订阅
func (p *Publisher) Subscribe() chan interface{} {
return p.SubscribeTopic(nil)
}
// SubscribeTopic 通过Topic订阅
func (p *Publisher) SubscribeTopic(topic topicFunc) chan interface{} {
ch := make(chan interface{}, p.buffer)
p.m.Lock()
p.subscribers[ch] = topic
p.m.Unlock()
return ch
}
// SubscribeTopicWithBuffer 通过自定义chan缓冲区大小定义新的订阅者
func (p *Publisher) SubscribeTopicWithBuffer(topic topicFunc, buffer int) chan interface{} {
ch := make(chan interface{}, buffer)
p.m.Lock()
p.subscribers[ch] = topic
p.m.Unlock()
return ch
}
// Evict 移除某个订阅者
func (p *Publisher) Evict(sub chan interface{}) {
p.m.Lock()
_, exists := p.subscribers[sub]
if exists {
delete(p.subscribers, sub)
close(sub)
}
p.m.Unlock()
}
// Publish 发布消息
func (p *Publisher) Publish(v interface{}) {
p.m.RLock()
if len(p.subscribers) == 0 {
p.m.RUnlock()
return
}
wg := wgPool.Get().(*sync.WaitGroup)
for sub, topic := range p.subscribers {
wg.Add(1)
go p.sendTopic(sub, topic, v, wg)
}
wg.Wait()
wgPool.Put(wg)
p.m.RUnlock()
}
// Close 关闭服务
func (p *Publisher) Close() {
p.m.Lock()
for sub := range p.subscribers {
delete(p.subscribers, sub)
close(sub)
}
p.m.Unlock()
}
// 真正发布消息的逻辑通过Timer根据传入的timeout控制每次发布消息最大阻塞时长
func (p *Publisher) sendTopic(sub subscriber, topic topicFunc, v interface{}, wg *sync.WaitGroup) {
defer wg.Done()
if topic != nil && !topic(v) {
return
}
// 如果接收器不可用,请在选择“不阻止”下发送
if p.timeout > 0 {
timeout := time.NewTimer(p.timeout)
defer timeout.Stop()
select {
case sub <- v:
case <-timeout.C:
}
return
}
select {
case sub <- v:
default:
}
}

@ -0,0 +1,38 @@
package gojobs
import (
"context"
"github.com/go-redis/redis/v9"
"log"
)
// Publish 发布
// ctx 上下文
// channel 频道
// message 消息
func (c *Client) Publish(ctx context.Context, channel string, message interface{}) error {
publish, err := c.cache.redisClient.Publish(ctx, channel, message).Result()
if c.config.debug == true {
log.Printf("[jobs.Publish] %s %s %v %s\n", channel, message, publish, err)
}
return err
}
type SubscribeResult struct {
err error
Message *redis.PubSub
}
// Subscribe 订阅
func (c *Client) Subscribe(ctx context.Context) SubscribeResult {
return SubscribeResult{
Message: c.cache.redisClient.Subscribe(ctx, c.cache.cornKeyPrefix+"_"+c.cache.cornKeyCustom),
}
}
// PSubscribe 订阅,支持通配符匹配(ch_user_*)
func (c *Client) PSubscribe(ctx context.Context) SubscribeResult {
return SubscribeResult{
Message: c.cache.redisClient.PSubscribe(ctx, c.cache.cornKeyPrefix+"_"+c.cache.cornKeyCustom+"_*"),
}
}

@ -18,7 +18,7 @@ import (
// ---
// address 下发地址
// err 错误信息
func (j *JobsGorm) GetIssueAddress(ctx context.Context, workers []string, v *jobs_gorm_model.Task) (string, error) {
func (c *Client) GetIssueAddress(ctx context.Context, workers []string, v *jobs_gorm_model.Task) (string, error) {
var (
currentIp = "" // 当前Ip
appointIpStatus = false // 指定Ip状态
@ -55,7 +55,7 @@ func (j *JobsGorm) GetIssueAddress(ctx context.Context, workers []string, v *job
return "", errors.New(fmt.Sprintf("需要执行的[%s]客户端不在线", currentIp))
} else {
// 随机返回一个
address := workers[j.random(0, len(workers))]
address := workers[c.random(0, len(workers))]
if address == "" {
return address, errors.New("获取执行的客户端异常")
}
@ -65,14 +65,14 @@ func (j *JobsGorm) GetIssueAddress(ctx context.Context, workers []string, v *job
}
// GetSubscribeClientList 获取在线的客户端
func (j *JobsGorm) GetSubscribeClientList(ctx context.Context) (client []string, err error) {
func (c *Client) GetSubscribeClientList(ctx context.Context) (client []string, err error) {
if j.config.logDebug == true {
log.Printf("[jobs.GetSubscribeClientList] %s\n", j.config.cornKeyPrefix+"_*")
if c.config.debug == true {
log.Printf("[jobs.GetSubscribeClientList] %s\n", c.cache.cornKeyPrefix+"_*")
}
// 查询活跃的channel
client, err = j.redisClient.PubSubChannels(ctx, j.config.cornKeyPrefix+"_*").Result()
client, err = c.cache.redisClient.PubSubChannels(ctx, c.cache.cornKeyPrefix+"_*").Result()
return client, err
}
@ -80,7 +80,7 @@ func (j *JobsGorm) GetSubscribeClientList(ctx context.Context) (client []string,
// 随机返回一个
// min最小
// max最大
func (j *JobsGorm) random(min, max int) int {
func (c *Client) random(min, max int) int {
if max-min <= 0 {
return 0
}

@ -2,25 +2,40 @@ package gojobs
import (
"go.dtapp.net/gojobs/jobs_gorm_model"
"go.dtapp.net/gojobs/jobs_mongo_model"
"go.dtapp.net/gostring"
"go.dtapp.net/gotime"
"go.mongodb.org/mongo-driver/bson/primitive"
"log"
)
// Run 运行
func (j *JobsGorm) Run(info jobs_gorm_model.Task, status int, result string) {
func (c *Client) Run(info jobs_gorm_model.Task, status int, result string) {
// 请求函数记录
err := j.gormClient.Db.Create(&jobs_gorm_model.TaskLog{
err := c.db.gormClient.Db.Create(&jobs_gorm_model.TaskLog{
TaskId: info.Id,
StatusCode: status,
Desc: result,
Version: j.config.runVersion,
Version: c.config.runVersion,
}).Error
if err != nil {
log.Println("[gojobs.Run.Create]", err.Error())
}
// 记录
if c.db.mongoClient != nil && c.db.mongoClient.Db != nil {
go func() {
c.db.mongoClient.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLog{}.TableName()).InsertOne(&jobs_mongo_model.TaskLog{
Id: primitive.NewObjectID(),
TaskId: info.Id,
StatusCode: status,
Desc: result,
Version: c.config.runVersion,
CreatedAt: primitive.NewDateTimeFromTime(gotime.Current().Time),
})
}()
}
if status == 0 {
err = j.EditTask(j.gormClient.Db, info.Id).
err = c.EditTask(c.db.gormClient.Db, info.Id).
Select("run_id", "result", "next_run_time").
Updates(jobs_gorm_model.Task{
RunId: gostring.GetUuId(),
@ -35,13 +50,13 @@ func (j *JobsGorm) Run(info jobs_gorm_model.Task, status int, result string) {
// 任务
if status == CodeSuccess {
// 执行成功
err = j.EditTask(j.gormClient.Db, info.Id).
err = c.EditTask(c.db.gormClient.Db, info.Id).
Select("status_desc", "number", "run_id", "updated_ip", "result", "next_run_time").
Updates(jobs_gorm_model.Task{
StatusDesc: "执行成功",
Number: info.Number + 1,
RunId: gostring.GetUuId(),
UpdatedIp: j.config.outsideIp,
UpdatedIp: c.config.outsideIp,
Result: result,
NextRunTime: gotime.Current().AfterSeconds(info.Frequency).Time,
}).Error
@ -51,13 +66,13 @@ func (j *JobsGorm) Run(info jobs_gorm_model.Task, status int, result string) {
}
if status == CodeEnd {
// 执行成功、提前结束
err = j.EditTask(j.gormClient.Db, info.Id).
err = c.EditTask(c.db.gormClient.Db, info.Id).
Select("status", "status_desc", "number", "updated_ip", "result", "next_run_time").
Updates(jobs_gorm_model.Task{
Status: TASK_SUCCESS,
StatusDesc: "结束执行",
Number: info.Number + 1,
UpdatedIp: j.config.outsideIp,
UpdatedIp: c.config.outsideIp,
Result: result,
NextRunTime: gotime.Current().Time,
}).Error
@ -67,13 +82,13 @@ func (j *JobsGorm) Run(info jobs_gorm_model.Task, status int, result string) {
}
if status == CodeError {
// 执行失败
err = j.EditTask(j.gormClient.Db, info.Id).
err = c.EditTask(c.db.gormClient.Db, info.Id).
Select("status_desc", "number", "run_id", "updated_ip", "result", "next_run_time").
Updates(jobs_gorm_model.Task{
StatusDesc: "执行失败",
Number: info.Number + 1,
RunId: gostring.GetUuId(),
UpdatedIp: j.config.outsideIp,
UpdatedIp: c.config.outsideIp,
Result: result,
NextRunTime: gotime.Current().AfterSeconds(info.Frequency).Time,
}).Error
@ -84,7 +99,7 @@ func (j *JobsGorm) Run(info jobs_gorm_model.Task, status int, result string) {
if info.MaxNumber != 0 {
if info.Number+1 >= info.MaxNumber {
// 关闭执行
err = j.EditTask(j.gormClient.Db, info.Id).
err = c.EditTask(c.db.gormClient.Db, info.Id).
Select("status").
Updates(jobs_gorm_model.Task{
Status: TASK_TIMEOUT,
@ -97,16 +112,33 @@ func (j *JobsGorm) Run(info jobs_gorm_model.Task, status int, result string) {
}
// RunAddLog 任务执行日志
func (j *JobsGorm) RunAddLog(id uint, runId string) error {
return j.gormClient.Db.Create(&jobs_gorm_model.TaskLogRun{
func (c *Client) RunAddLog(id uint, runId string) error {
if c.db.mongoClient != nil && c.db.mongoClient.Db != nil {
go func() {
c.db.mongoClient.Database(c.db.mongoDatabaseName).Collection(jobs_mongo_model.TaskLogRun{}.TableName()).InsertOne(&jobs_mongo_model.TaskLogRun{
Id: primitive.NewObjectID(),
TaskId: id,
RunId: runId,
InsideIp: c.config.insideIp,
OutsideIp: c.config.outsideIp,
Os: c.config.os,
Arch: c.config.arch,
Gomaxprocs: c.config.maxProCs,
GoVersion: c.config.version,
MacAddrs: c.config.macAddrS,
CreatedAt: primitive.NewDateTimeFromTime(gotime.Current().Time),
})
}()
}
return c.db.gormClient.Db.Create(&jobs_gorm_model.TaskLogRun{
TaskId: id,
RunId: runId,
InsideIp: j.config.insideIp,
OutsideIp: j.config.outsideIp,
Os: j.config.os,
Arch: j.config.arch,
Gomaxprocs: j.config.maxProCs,
GoVersion: j.config.version,
MacAddrs: j.config.macAddrS,
InsideIp: c.config.insideIp,
OutsideIp: c.config.outsideIp,
Os: c.config.os,
Arch: c.config.arch,
Gomaxprocs: c.config.maxProCs,
GoVersion: c.config.version,
MacAddrs: c.config.macAddrS,
}).Error
}
Loading…
Cancel
Save