From f81689dfb1771a67a6056051f4b0fe46ae66f617 Mon Sep 17 00:00:00 2001 From: Ming Deng Date: Sat, 30 Jul 2022 16:11:51 +0800 Subject: [PATCH] Release v2.0.5 (#5033) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add: generic cache random time offset expired. * bugfix: Csrf token should be Secure and httpOnly, but not now * fix: expose the Offset property to allow external modifications * improving the concurrency performance of random value calculation * add WithOffsetFunc to define private RandomExpireCache.offset field * fix: add seconds definition * build(deps): bump github.com/stretchr/testify from 1.7.1 to 1.8.0 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.1 to 1.8.0. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.7.1...v1.8.0) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * fix 4907: force admin service http only * Feat: add get all tasks function (#4999) * feat: add get all tasks function * Refine Comments : admin/profile.go,bean/mock.go,config/global.go... (#5009) * Refine Comments * refine comments for cache.go * refine comments for log.go * Update orm.go * refine comments for orm_log.go,types.go * Update utils.go * Update doc.go * refine comments for for four files (#5011) * refine comments for cache.go * refine comments for log.go * Update orm.go * refine comments for orm_log.go,types.go * Update utils.go * Update doc.go * Update db.go * fix pass []any as any in variadic function by asasalint (#5012) * fix pass []any as any in variadic function * add change log * build(deps): bump go.opentelemetry.io/otel/trace from 1.7.0 to 1.8.0 (#5019) Bumps [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) from 1.7.0 to 1.8.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.7.0...v1.8.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/trace dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * refine comments for package core (#5014) * Refine Comments * refine comments for cache.go * refine comments for log.go * Update orm.go * refine comments for orm_log.go,types.go * Update utils.go * Update doc.go * refine comments * refine comments * Update db.go * refine comments for core * build(deps): bump go.opentelemetry.io/otel/exporters/stdout/stdouttrace (#5018) Bumps [go.opentelemetry.io/otel/exporters/stdout/stdouttrace](https://github.com/open-telemetry/opentelemetry-go) from 1.7.0 to 1.8.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.7.0...v1.8.0) --- updated-dependencies: - dependency-name: go.opentelemetry.io/otel/exporters/stdout/stdouttrace dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix 5022: Miss assiging ln to graceful Server (#5028) * prepare for releasing v2.0.5 (#5032) Co-authored-by: auual Co-authored-by: Leon Ding Co-authored-by: dada0z Co-authored-by: kevinzeng Co-authored-by: Kevin Tsang <39397413+ktalg@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: 日暮颂歌1991 <448081525@qq.com> Co-authored-by: Regan Yue <1131625869@qq.com> Co-authored-by: alingse --- CHANGELOG.md | 12 +++ adapter/app.go | 2 +- adapter/cache/cache.go | 16 ++-- adapter/context/context.go | 4 +- adapter/context/output.go | 2 +- adapter/doc.go | 2 +- adapter/logs/log.go | 2 +- adapter/orm/db_alias.go | 2 +- adapter/orm/orm.go | 35 ++++---- adapter/orm/orm_log.go | 2 +- adapter/orm/types.go | 32 ++++---- adapter/orm/utils.go | 8 +- adapter/router.go | 2 +- client/cache/cache.go | 12 +-- client/cache/random_expired_cache.go | 75 +++++++++++++++++ client/cache/random_expired_cache_test.go | 99 +++++++++++++++++++++++ client/httplib/client_option.go | 4 +- client/orm/db.go | 44 +++++----- client/orm/mock/mock_orm.go | 2 +- core/admin/profile.go | 2 +- core/bean/doc.go | 2 +- core/bean/mock.go | 2 +- core/berror/error.go | 2 +- core/config/config.go | 10 +-- core/config/global.go | 10 +-- core/config/toml/toml.go | 5 +- core/utils/time.go | 2 +- go.mod | 12 +-- go.sum | 28 +++---- server/web/admin.go | 4 +- server/web/context/context.go | 2 +- server/web/grace/server.go | 1 + task/task.go | 23 +++++- task/task_test.go | 21 +++++ 34 files changed, 356 insertions(+), 127 deletions(-) create mode 100644 client/cache/random_expired_cache.go create mode 100644 client/cache/random_expired_cache_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c4b9949..f25b7dd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,16 @@ # developing + +# v2.0.5 + +Note: now we force the web admin service serving HTTP only. + +- [Fix 4984: random expire cache](https://github.com/beego/beego/pull/4984) +- [Fix 4907: make admin serve HTTP only](https://github.com/beego/beego/pull/5005) +- [Feat 4999: add get all tasks function](https://github.com/beego/beego/pull/4999) +- [Fix 5012: fix some bug, pass []any as any in variadic function](https://github.com/beego/beego/pull/5012) +- [Fix 5022: Miss assigning listener to graceful Server](https://github.com/beego/beego/pull/5028) + + # v2.0.4 Note: now we force the web admin service serving HTTP only. diff --git a/adapter/app.go b/adapter/app.go index 35570616..aaf85a17 100644 --- a/adapter/app.go +++ b/adapter/app.go @@ -245,7 +245,7 @@ func Any(rootpath string, f FilterFunc) *App { // fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) // })) func Handler(rootpath string, h http.Handler, options ...interface{}) *App { - return (*App)(web.Handler(rootpath, h, options)) + return (*App)(web.Handler(rootpath, h, options...)) } // InsertFilter adds a FilterFunc with pattern condition and action constant. diff --git a/adapter/cache/cache.go b/adapter/cache/cache.go index 0465e4c1..bad35cfe 100644 --- a/adapter/cache/cache.go +++ b/adapter/cache/cache.go @@ -47,23 +47,23 @@ import ( // c.Incr("counter") // now is 2 // count := c.Get("counter").(int) type Cache interface { - // get cached value by key. + // Get will get cached value by key. Get(key string) interface{} // GetMulti is a batch version of Get. GetMulti(keys []string) []interface{} - // set cached value with key and expire time. + // Put will set cached value with key and expire time. Put(key string, val interface{}, timeout time.Duration) error - // delete cached value by key. + // Delete will delete cached value by key. Delete(key string) error - // increase cached int value by key, as a counter. + // Incr will increase cached int value by key, as a counter. Incr(key string) error - // decrease cached int value by key, as a counter. + // Decr will decrease cached int value by key, as a counter. Decr(key string) error - // check if cached value exists or not. + // IsExist can check if cached value exists or not. IsExist(key string) bool - // clear all cache. + // ClearAll will clear all cache. ClearAll() error - // start gc routine based on config string settings. + // StartAndGC will start gc routine based on config string settings. StartAndGC(config string) error } diff --git a/adapter/context/context.go b/adapter/context/context.go index c0259139..77a0aa05 100644 --- a/adapter/context/context.go +++ b/adapter/context/context.go @@ -78,7 +78,7 @@ func (ctx *Context) GetCookie(key string) string { // SetCookie Set cookie for response. // It's alias of BeegoOutput.Cookie. func (ctx *Context) SetCookie(name string, value string, others ...interface{}) { - (*context.Context)(ctx).SetCookie(name, value, others) + (*context.Context)(ctx).SetCookie(name, value, others...) } // GetSecureCookie Get secure cookie from request by a given key. @@ -88,7 +88,7 @@ func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) { // SetSecureCookie Set Secure cookie for response. func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) { - (*context.Context)(ctx).SetSecureCookie(Secret, name, value, others) + (*context.Context)(ctx).SetSecureCookie(Secret, name, value, others...) } // XSRFToken creates a xsrf token string and returns. diff --git a/adapter/context/output.go b/adapter/context/output.go index 5152ccf5..46edd343 100644 --- a/adapter/context/output.go +++ b/adapter/context/output.go @@ -47,7 +47,7 @@ func (output *BeegoOutput) Body(content []byte) error { // Cookie sets cookie value via given key. // others are ordered as cookie's max age time, path,domain, secure and httponly. func (output *BeegoOutput) Cookie(name string, value string, others ...interface{}) { - (*context.BeegoOutput)(output).Cookie(name, value, others) + (*context.BeegoOutput)(output).Cookie(name, value, others...) } // JSON writes json to response body. diff --git a/adapter/doc.go b/adapter/doc.go index c8f2174c..ef4bdffd 100644 --- a/adapter/doc.go +++ b/adapter/doc.go @@ -12,5 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -// used to keep compatible with v1.x +// Package adapter used to keep compatible with v1.x package adapter diff --git a/adapter/logs/log.go b/adapter/logs/log.go index fc0fdc62..3cedfdde 100644 --- a/adapter/logs/log.go +++ b/adapter/logs/log.go @@ -158,7 +158,7 @@ func (bl *BeeLogger) EnableFuncCallDepth(b bool) { (*logs.BeeLogger)(bl).EnableFuncCallDepth(b) } -// set prefix +// SetPrefix will set prefix func (bl *BeeLogger) SetPrefix(s string) { (*logs.BeeLogger)(bl).SetPrefix(s) } diff --git a/adapter/orm/db_alias.go b/adapter/orm/db_alias.go index f910c3f9..a196ca23 100644 --- a/adapter/orm/db_alias.go +++ b/adapter/orm/db_alias.go @@ -69,7 +69,7 @@ func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{} } func (d *DB) QueryRow(query string, args ...interface{}) *sql.Row { - return (*orm.DB)(d).QueryRow(query, args) + return (*orm.DB)(d).QueryRow(query, args...) } func (d *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row { diff --git a/adapter/orm/orm.go b/adapter/orm/orm.go index fd3c3d25..0ebe478e 100644 --- a/adapter/orm/orm.go +++ b/adapter/orm/orm.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build go1.8 // +build go1.8 // Package orm provide ORM for MySQL/PostgreSQL/sqlite @@ -92,7 +93,7 @@ type ormer struct { var _ Ormer = new(ormer) -// read data to model +// Read read data to model func (o *ormer) Read(md interface{}, cols ...string) error { if o.isTx { return o.txDelegate.Read(md, cols...) @@ -100,7 +101,7 @@ func (o *ormer) Read(md interface{}, cols ...string) error { return o.delegate.Read(md, cols...) } -// read data to model, like Read(), but use "SELECT FOR UPDATE" form +// ReadForUpdate read data to model, like Read(), but use "SELECT FOR UPDATE" form func (o *ormer) ReadForUpdate(md interface{}, cols ...string) error { if o.isTx { return o.txDelegate.ReadForUpdate(md, cols...) @@ -108,7 +109,7 @@ func (o *ormer) ReadForUpdate(md interface{}, cols ...string) error { return o.delegate.ReadForUpdate(md, cols...) } -// Try to read a row from the database, or insert one if it doesn't exist +// ReadOrCreate Try to read a row from the database, or insert one if it doesn't exist func (o *ormer) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) { if o.isTx { return o.txDelegate.ReadOrCreate(md, col1, cols...) @@ -116,7 +117,7 @@ func (o *ormer) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, return o.delegate.ReadOrCreate(md, col1, cols...) } -// insert model data to database +// Insert will insert model data to database func (o *ormer) Insert(md interface{}) (int64, error) { if o.isTx { return o.txDelegate.Insert(md) @@ -124,7 +125,7 @@ func (o *ormer) Insert(md interface{}) (int64, error) { return o.delegate.Insert(md) } -// insert some models to database +// InsertMulti will insert some models to database func (o *ormer) InsertMulti(bulk int, mds interface{}) (int64, error) { if o.isTx { return o.txDelegate.InsertMulti(bulk, mds) @@ -140,7 +141,7 @@ func (o *ormer) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int return o.delegate.InsertOrUpdate(md, colConflitAndArgs...) } -// update model to database. +// Update will update model to database. // cols set the columns those want to update. func (o *ormer) Update(md interface{}, cols ...string) (int64, error) { if o.isTx { @@ -149,7 +150,7 @@ func (o *ormer) Update(md interface{}, cols ...string) (int64, error) { return o.delegate.Update(md, cols...) } -// delete model in database +// Delete delete model in database // cols shows the delete conditions values read from. default is pk func (o *ormer) Delete(md interface{}, cols ...string) (int64, error) { if o.isTx { @@ -158,7 +159,7 @@ func (o *ormer) Delete(md interface{}, cols ...string) (int64, error) { return o.delegate.Delete(md, cols...) } -// create a models to models queryer +// QueryM2M create a models to models queryer func (o *ormer) QueryM2M(md interface{}, name string) QueryM2Mer { if o.isTx { return o.txDelegate.QueryM2M(md, name) @@ -166,7 +167,7 @@ func (o *ormer) QueryM2M(md interface{}, name string) QueryM2Mer { return o.delegate.QueryM2M(md, name) } -// load related models to md model. +// LoadRelated load related models to md model. // args are limit, offset int and order string. // // example: @@ -200,7 +201,7 @@ func (o *ormer) LoadRelated(md interface{}, name string, args ...interface{}) (i return o.delegate.LoadRelated(md, name, kvs...) } -// return a QuerySeter for table operations. +// QueryTable return a QuerySeter for table operations. // table name can be string or struct. // e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)), func (o *ormer) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) { @@ -210,7 +211,7 @@ func (o *ormer) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) { return o.delegate.QueryTable(ptrStructOrTableName) } -// switch to another registered database driver by given name. +// Using switch to another registered database driver by given name. func (o *ormer) Using(name string) error { if o.isTx { return ErrTxHasBegan @@ -219,7 +220,7 @@ func (o *ormer) Using(name string) error { return nil } -// begin transaction +// Begin will begin transaction func (o *ormer) Begin() error { if o.isTx { return ErrTxHasBegan @@ -240,7 +241,7 @@ func (o *ormer) BeginTx(ctx context.Context, opts *sql.TxOptions) error { return nil } -// commit transaction +// Commit will commit transaction func (o *ormer) Commit() error { if !o.isTx { return ErrTxDone @@ -255,7 +256,7 @@ func (o *ormer) Commit() error { return err } -// rollback transaction +// Rollback will rollback transaction func (o *ormer) Rollback() error { if !o.isTx { return ErrTxDone @@ -270,7 +271,7 @@ func (o *ormer) Rollback() error { return err } -// return a raw query seter for raw sql string. +// Raw return a raw query seter for raw sql string. func (o *ormer) Raw(query string, args ...interface{}) RawSeter { if o.isTx { return o.txDelegate.Raw(query, args...) @@ -278,7 +279,7 @@ func (o *ormer) Raw(query string, args ...interface{}) RawSeter { return o.delegate.Raw(query, args...) } -// return current using database Driver +// Driver return current using database Driver func (o *ormer) Driver() Driver { if o.isTx { return o.txDelegate.Driver() @@ -286,7 +287,7 @@ func (o *ormer) Driver() Driver { return o.delegate.Driver() } -// return sql.DBStats for current database +// DBStats return sql.DBStats for current database func (o *ormer) DBStats() *sql.DBStats { if o.isTx { return o.txDelegate.DBStats() diff --git a/adapter/orm/orm_log.go b/adapter/orm/orm_log.go index 98c1522e..1faab4ba 100644 --- a/adapter/orm/orm_log.go +++ b/adapter/orm/orm_log.go @@ -23,7 +23,7 @@ import ( // Log implement the log.Logger type Log orm.Log -// costomer log func +// LogFunc is costomer log func var LogFunc = orm.LogFunc // NewLog set io.Writer to create a Logger. diff --git a/adapter/orm/types.go b/adapter/orm/types.go index 428f8b14..ecc4d6f4 100644 --- a/adapter/orm/types.go +++ b/adapter/orm/types.go @@ -35,7 +35,7 @@ type Fielder orm.Fielder // Ormer define the orm interface type Ormer interface { - // read data to model + // Read read data to model // for example: // this will find User by Id field // u = &User{Id: user.Id} @@ -44,25 +44,25 @@ type Ormer interface { // u = &User{UserName: "astaxie", Password: "pass"} // err = Ormer.Read(u, "UserName") Read(md interface{}, cols ...string) error - // Like Read(), but with "FOR UPDATE" clause, useful in transaction. + // ReadForUpdate Like Read(), but with "FOR UPDATE" clause, useful in transaction. // Some databases are not support this feature. ReadForUpdate(md interface{}, cols ...string) error - // Try to read a row from the database, or insert one if it doesn't exist + // ReadOrCreate Try to read a row from the database, or insert one if it doesn't exist ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) - // insert model data to database + // Insert will insert model data to database // for example: // user := new(User) // id, err = Ormer.Insert(user) // user must be a pointer and Insert will set user's pk field Insert(interface{}) (int64, error) - // mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value") + // InsertOrUpdate(model,"colu=colu+value") or mysql:InsertOrUpdate(model) // if colu type is integer : can use(+-*/), string : convert(colu,"value") // postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value") // if colu type is integer : can use(+-*/), string : colu || "value" InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) - // insert some models to database + // InsertMulti insert some models to database InsertMulti(bulk int, mds interface{}) (int64, error) - // update model to database. + // Update update model to database. // cols set the columns those want to update. // find model by Id(pk) field and update columns specified by fields, if cols is null then update all columns // for example: @@ -72,9 +72,9 @@ type Ormer interface { // user.Extra.Data = "orm" // num, err = Ormer.Update(&user, "Langs", "Extra") Update(md interface{}, cols ...string) (int64, error) - // delete model in database + // Delete delete model in database Delete(md interface{}, cols ...string) (int64, error) - // load related models to md model. + // LoadRelated load related models to md model. // args are limit, offset int and order string. // // example: @@ -87,25 +87,25 @@ type Ormer interface { // args[3] string order for example : "-Id" // make sure the relation is defined in model struct tags. LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) - // create a models to models queryer + // QueryM2M create a models to models queryer // for example: // post := Post{Id: 4} // m2m := Ormer.QueryM2M(&post, "Tags") QueryM2M(md interface{}, name string) QueryM2Mer - // return a QuerySeter for table operations. + // QueryTable return a QuerySeter for table operations. // table name can be string or struct. // e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)), QueryTable(ptrStructOrTableName interface{}) QuerySeter // switch to another registered database driver by given name. Using(name string) error - // begin transaction + // Begin begin transaction // for example: // o := NewOrm() // err := o.Begin() // ... // err = o.Rollback() Begin() error - // begin transaction with provided context and option + // BeginTx begin transaction with provided context and option // the provided context is used until the transaction is committed or rolled back. // if the context is canceled, the transaction will be rolled back. // the provided TxOptions is optional and may be nil if defaults should be used. @@ -116,11 +116,11 @@ type Ormer interface { // ... // err = o.Rollback() BeginTx(ctx context.Context, opts *sql.TxOptions) error - // commit transaction + // Commit commit transaction Commit() error - // rollback transaction + // Rollback rollback transaction Rollback() error - // return a raw query seter for raw sql string. + // Raw return a raw query seter for raw sql string. // for example: // ormer.Raw("UPDATE `user` SET `user_name` = ? WHERE `user_name` = ?", "slene", "testing").Exec() // // update user testing's name to slene diff --git a/adapter/orm/utils.go b/adapter/orm/utils.go index cd54f867..a88836c3 100644 --- a/adapter/orm/utils.go +++ b/adapter/orm/utils.go @@ -246,7 +246,7 @@ func camelString(s string) string { type argString []string -// get string by index from string slice +// Get will get string by index from string slice func (a argString) Get(i int, args ...string) (r string) { if i >= 0 && i < len(a) { r = a[i] @@ -258,7 +258,7 @@ func (a argString) Get(i int, args ...string) (r string) { type argInt []int -// get int by index from int slice +// Get will get int by index from int slice func (a argInt) Get(i int, args ...int) (r int) { if i >= 0 && i < len(a) { r = a[i] @@ -269,13 +269,13 @@ func (a argInt) Get(i int, args ...int) (r int) { return } -// parse time to string with location +// timeParse parse time to string with location func timeParse(dateString, format string) (time.Time, error) { tp, err := time.ParseInLocation(format, dateString, DefaultTimeLoc) return tp, err } -// get pointer indirect type +// indirectType get pointer indirect type func indirectType(v reflect.Type) reflect.Type { switch v.Kind() { case reflect.Ptr: diff --git a/adapter/router.go b/adapter/router.go index a0add1fe..23f08e1e 100644 --- a/adapter/router.go +++ b/adapter/router.go @@ -212,7 +212,7 @@ func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) { // Handler add user defined Handler func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) { - (*web.ControllerRegister)(p).Handler(pattern, h, options) + (*web.ControllerRegister)(p).Handler(pattern, h, options...) } // AddAuto router to ControllerRegister. diff --git a/client/cache/cache.go b/client/cache/cache.go index 2f9dd9bd..1eafccdc 100644 --- a/client/cache/cache.go +++ b/client/cache/cache.go @@ -53,21 +53,21 @@ type Cache interface { Get(ctx context.Context, key string) (interface{}, error) // GetMulti is a batch version of Get. GetMulti(ctx context.Context, keys []string) ([]interface{}, error) - // Set a cached value with key and expire time. + // Put Set a cached value with key and expire time. Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error // Delete cached value by key. // Should not return error if key not found Delete(ctx context.Context, key string) error - // Increment a cached int value by key, as a counter. + // Incr Increment a cached int value by key, as a counter. Incr(ctx context.Context, key string) error - // Decrement a cached int value by key, as a counter. + // Decr Decrement a cached int value by key, as a counter. Decr(ctx context.Context, key string) error - // Check if a cached value exists or not. + // IsExist Check if a cached value exists or not. // if key is expired, return (false, nil) IsExist(ctx context.Context, key string) (bool, error) - // Clear all cache. + // ClearAll Clear all cache. ClearAll(ctx context.Context) error - // Start gc routine based on config string settings. + // StartAndGC Start gc routine based on config string settings. StartAndGC(config string) error } diff --git a/client/cache/random_expired_cache.go b/client/cache/random_expired_cache.go new file mode 100644 index 00000000..26200112 --- /dev/null +++ b/client/cache/random_expired_cache.go @@ -0,0 +1,75 @@ +// Copyright 2014 beego Author. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "context" + "math/rand" + "sync/atomic" + "time" +) + +// RandomExpireCacheOption implement genreate random time offset expired option +type RandomExpireCacheOption func(*RandomExpireCache) + +// WithOffsetFunc returns a RandomExpireCacheOption that configures the offset function +func WithOffsetFunc(fn func() time.Duration) RandomExpireCacheOption { + return func(cache *RandomExpireCache) { + cache.offset = fn + } +} + +// RandomExpireCache prevent cache batch invalidation +// Cache random time offset expired +type RandomExpireCache struct { + Cache + offset func() time.Duration +} + +// Put random time offset expired +func (rec *RandomExpireCache) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error { + timeout += rec.offset() + return rec.Cache.Put(ctx, key, val, timeout) +} + +// NewRandomExpireCache return random expire cache struct +func NewRandomExpireCache(adapter Cache, opts ...RandomExpireCacheOption) Cache { + rec := RandomExpireCache{ + Cache: adapter, + offset: defaultExpiredFunc(), + } + for _, fn := range opts { + fn(&rec) + } + return &rec +} + +// defaultExpiredFunc return a func that used to generate random time offset (range: [3s,8s)) expired +func defaultExpiredFunc() func() time.Duration { + const size = 5 + var randTimes [size]time.Duration + for i := range randTimes { + randTimes[i] = time.Duration(i+3) * time.Second + } + // shuffle values + for i := range randTimes { + n := rand.Intn(size) + randTimes[i], randTimes[n] = randTimes[n], randTimes[i] + } + var i uint64 + return func() time.Duration { + return randTimes[atomic.AddUint64(&i, 1)%size] + } +} diff --git a/client/cache/random_expired_cache_test.go b/client/cache/random_expired_cache_test.go new file mode 100644 index 00000000..1e3bb935 --- /dev/null +++ b/client/cache/random_expired_cache_test.go @@ -0,0 +1,99 @@ +// Copyright 2014 beego Author. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "context" + "math/rand" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestRandomExpireCache(t *testing.T) { + bm, err := NewCache("memory", `{"interval":20}`) + assert.Nil(t, err) + + cache := NewRandomExpireCache(bm) + // should not be nil + assert.NotNil(t, cache.(*RandomExpireCache).offset) + + timeoutDuration := 3 * time.Second + + if err = cache.Put(context.Background(), "Leon Ding", 22, timeoutDuration); err != nil { + t.Error("set Error", err) + } + + // testing random expire cache + time.Sleep(timeoutDuration + 3 + time.Second) + + if res, _ := cache.IsExist(context.Background(), "Leon Ding"); !res { + t.Error("check err") + } + + if v, _ := cache.Get(context.Background(), "Leon Ding"); v.(int) != 22 { + t.Error("get err") + } + + cache.Delete(context.Background(), "Leon Ding") + res, _ := cache.IsExist(context.Background(), "Leon Ding") + assert.False(t, res) + + assert.Nil(t, cache.Put(context.Background(), "Leon Ding", "author", timeoutDuration)) + + cache.Delete(context.Background(), "astaxie") + res, _ = cache.IsExist(context.Background(), "astaxie") + assert.False(t, res) + + assert.Nil(t, cache.Put(context.Background(), "astaxie", "author", timeoutDuration)) + + res, _ = cache.IsExist(context.Background(), "astaxie") + assert.True(t, res) + + v, _ := cache.Get(context.Background(), "astaxie") + assert.Equal(t, "author", v) + + assert.Nil(t, cache.Put(context.Background(), "astaxie1", "author1", timeoutDuration)) + + res, _ = cache.IsExist(context.Background(), "astaxie1") + assert.True(t, res) + + vv, _ := cache.GetMulti(context.Background(), []string{"astaxie", "astaxie1"}) + assert.Equal(t, 2, len(vv)) + assert.Equal(t, "author", vv[0]) + assert.Equal(t, "author1", vv[1]) + + vv, err = cache.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"}) + assert.Equal(t, 2, len(vv)) + assert.Nil(t, vv[0]) + assert.Equal(t, "author1", vv[1]) + + assert.NotNil(t, err) + assert.True(t, strings.Contains(err.Error(), "key isn't exist")) +} + +func TestWithOffsetFunc(t *testing.T) { + bm, err := NewCache("memory", `{"interval":20}`) + assert.Nil(t, err) + + magic := -time.Duration(rand.Int()) + cache := NewRandomExpireCache(bm, WithOffsetFunc(func() time.Duration { + return magic + })) + // offset should return the magic value + assert.Equal(t, magic, cache.(*RandomExpireCache).offset()) +} diff --git a/client/httplib/client_option.go b/client/httplib/client_option.go index f970e67d..2b8b672c 100644 --- a/client/httplib/client_option.go +++ b/client/httplib/client_option.go @@ -33,7 +33,7 @@ func WithEnableCookie(enable bool) ClientOption { } } -// WithEnableCookie will adds UA in all subsequent request +// WithUserAgent will adds UA in all subsequent request func WithUserAgent(userAgent string) ClientOption { return func(client *Client) { client.Setting.UserAgent = userAgent @@ -105,7 +105,7 @@ func WithCookie(cookie *http.Cookie) BeegoHTTPRequestOption { } } -// Withtokenfactory adds a custom function to set Authorization +// WithTokenFactory adds a custom function to set Authorization func WithTokenFactory(tokenFactory func() string) BeegoHTTPRequestOption { return func(request *BeegoHTTPRequest) { t := tokenFactory() diff --git a/client/orm/db.go b/client/orm/db.go index 5da43d0a..08047a04 100644 --- a/client/orm/db.go +++ b/client/orm/db.go @@ -264,7 +264,7 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val return value, nil } -// create insert sql preparation statement object. +// PrepareInsert create insert sql preparation statement object. func (d *dbBase) PrepareInsert(ctx context.Context, q dbQuerier, mi *modelInfo) (stmtQuerier, string, error) { Q := d.ins.TableQuote() @@ -290,7 +290,7 @@ func (d *dbBase) PrepareInsert(ctx context.Context, q dbQuerier, mi *modelInfo) return stmt, query, err } -// insert struct with prepared statement and given struct reflect value. +// InsertStmt insert struct with prepared statement and given struct reflect value. func (d *dbBase) InsertStmt(ctx context.Context, stmt stmtQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) { values, _, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, nil, tz) if err != nil { @@ -371,7 +371,7 @@ func (d *dbBase) Read(ctx context.Context, q dbQuerier, mi *modelInfo, ind refle return nil } -// execute insert sql dbQuerier with given struct reflect.Value. +// Insert execute insert sql dbQuerier with given struct reflect.Value. func (d *dbBase) Insert(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) { names := make([]string, 0, len(mi.fields.dbcols)) values, autoFields, err := d.collectValues(mi, ind, mi.fields.dbcols, false, true, &names, tz) @@ -390,7 +390,7 @@ func (d *dbBase) Insert(ctx context.Context, q dbQuerier, mi *modelInfo, ind ref return id, err } -// multi-insert sql with given slice struct reflect.Value. +// InsertMulti multi-insert sql with given slice struct reflect.Value. func (d *dbBase) InsertMulti(ctx context.Context, q dbQuerier, mi *modelInfo, sind reflect.Value, bulk int, tz *time.Location) (int64, error) { var ( cnt int64 @@ -454,7 +454,7 @@ func (d *dbBase) InsertMulti(ctx context.Context, q dbQuerier, mi *modelInfo, si return cnt, err } -// execute insert sql with given struct and given values. +// InsertValue execute insert sql with given struct and given values. // insert the given values, not the field values in struct. func (d *dbBase) InsertValue(ctx context.Context, q dbQuerier, mi *modelInfo, isMulti bool, names []string, values []interface{}) (int64, error) { Q := d.ins.TableQuote() @@ -612,7 +612,7 @@ func (d *dbBase) InsertOrUpdate(ctx context.Context, q dbQuerier, mi *modelInfo, return id, err } -// execute update sql dbQuerier with given struct reflect.Value. +// Update execute update sql dbQuerier with given struct reflect.Value. func (d *dbBase) Update(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) { pkName, pkValue, ok := getExistPk(mi, ind) if !ok { @@ -677,7 +677,7 @@ func (d *dbBase) Update(ctx context.Context, q dbQuerier, mi *modelInfo, ind ref return 0, err } -// execute delete sql dbQuerier with given struct reflect.Value. +// Delete execute delete sql dbQuerier with given struct reflect.Value. // delete index is pk. func (d *dbBase) Delete(ctx context.Context, q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) { var whereCols []string @@ -725,7 +725,7 @@ func (d *dbBase) Delete(ctx context.Context, q dbQuerier, mi *modelInfo, ind ref return 0, err } -// update table-related record by querySet. +// UpdateBatch update table-related record by querySet. // need querySet not struct reflect.Value to update related records. func (d *dbBase) UpdateBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, params Params, tz *time.Location) (int64, error) { columns := make([]string, 0, len(params)) @@ -843,7 +843,7 @@ func (d *dbBase) deleteRels(ctx context.Context, q dbQuerier, mi *modelInfo, arg return nil } -// delete table-related records. +// DeleteBatch delete table-related records. func (d *dbBase) DeleteBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (int64, error) { tables := newDbTables(mi, d.ins) tables.skipEnd = true @@ -920,7 +920,7 @@ func (d *dbBase) DeleteBatch(ctx context.Context, q dbQuerier, qs *querySet, mi return 0, err } -// read related records. +// ReadBatch read related records. func (d *dbBase) ReadBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, container interface{}, tz *time.Location, cols []string) (int64, error) { val := reflect.ValueOf(container) ind := reflect.Indirect(val) @@ -1145,7 +1145,7 @@ func (d *dbBase) ReadBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *m return cnt, nil } -// excute count sql and return count result int64. +// Count excute count sql and return count result int64. func (d *dbBase) Count(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (cnt int64, err error) { tables := newDbTables(mi, d.ins) tables.parseRelated(qs.related, qs.relDepth) @@ -1173,7 +1173,7 @@ func (d *dbBase) Count(ctx context.Context, q dbQuerier, qs *querySet, mi *model return } -// generate sql with replacing operator string placeholders and replaced values. +// GenerateOperatorSQL generate sql with replacing operator string placeholders and replaced values. func (d *dbBase) GenerateOperatorSQL(mi *modelInfo, fi *fieldInfo, operator string, args []interface{}, tz *time.Location) (string, []interface{}) { var sql string params := getFlatParams(fi, args, tz) @@ -1233,7 +1233,7 @@ func (d *dbBase) GenerateOperatorSQL(mi *modelInfo, fi *fieldInfo, operator stri return sql, params } -// gernerate sql string with inner function, such as UPPER(text). +// GenerateOperatorLeftCol gernerate sql string with inner function, such as UPPER(text). func (d *dbBase) GenerateOperatorLeftCol(*fieldInfo, string, *string) { // default not use } @@ -1615,7 +1615,7 @@ setValue: return value, nil } -// query sql, read values , save to *[]ParamList. +// ReadValues query sql, read values , save to *[]ParamList. func (d *dbBase) ReadValues(ctx context.Context, q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, exprs []string, container interface{}, tz *time.Location) (int64, error) { var ( maps []Params @@ -1788,7 +1788,7 @@ func (d *dbBase) ReadValues(ctx context.Context, q dbQuerier, qs *querySet, mi * return cnt, nil } -// flag of update joined record. +// SupportUpdateJoin flag of update joined record. func (d *dbBase) SupportUpdateJoin() bool { return true } @@ -1797,12 +1797,12 @@ func (d *dbBase) MaxLimit() uint64 { return 18446744073709551615 } -// return quote. +// TableQuote return quote. func (d *dbBase) TableQuote() string { return "`" } -// replace value placeholder in parametered sql string. +// ReplaceMarks replace value placeholder in parametered sql string. func (d *dbBase) ReplaceMarks(query *string) { // default use `?` as mark, do nothing } @@ -1817,22 +1817,22 @@ func (d *dbBase) setval(ctx context.Context, db dbQuerier, mi *modelInfo, autoFi return nil } -// convert time from db. +// TimeFromDB convert time from db. func (d *dbBase) TimeFromDB(t *time.Time, tz *time.Location) { *t = t.In(tz) } -// convert time to db. +// TimeToDB convert time to db. func (d *dbBase) TimeToDB(t *time.Time, tz *time.Location) { *t = t.In(tz) } -// get database types. +// DbTypes get database types. func (d *dbBase) DbTypes() map[string]string { return nil } -// gt all tables. +// GetTables gt all tables. func (d *dbBase) GetTables(db dbQuerier) (map[string]bool, error) { tables := make(map[string]bool) query := d.ins.ShowTablesQuery() @@ -1857,7 +1857,7 @@ func (d *dbBase) GetTables(db dbQuerier) (map[string]bool, error) { return tables, nil } -// get all cloumns in table. +// GetColumns get all cloumns in table. func (d *dbBase) GetColumns(ctx context.Context, db dbQuerier, table string) (map[string][3]string, error) { columns := make(map[string][3]string) query := d.ins.ShowColumnsQuery(table) diff --git a/client/orm/mock/mock_orm.go b/client/orm/mock/mock_orm.go index 70bee4f7..ce6712a4 100644 --- a/client/orm/mock/mock_orm.go +++ b/client/orm/mock/mock_orm.go @@ -45,7 +45,7 @@ func MockMethod(method string, resp ...interface{}) *Mock { return NewMock(NewSimpleCondition("", method), resp, nil) } -// MockOrmRead support orm.Read and orm.ReadWithCtx +// MockRead support orm.Read and orm.ReadWithCtx // cb is used to mock read data from DB func MockRead(tableName string, cb func(data interface{}), err error) *Mock { return NewMock(NewSimpleCondition(tableName, "ReadWithCtx"), []interface{}{err}, func(inv *orm.Invocation) { diff --git a/core/admin/profile.go b/core/admin/profile.go index bd9eff4d..f85afaa2 100644 --- a/core/admin/profile.go +++ b/core/admin/profile.go @@ -144,7 +144,7 @@ func avg(items []time.Duration) time.Duration { return time.Duration(int64(sum) / int64(len(items))) } -// format bytes number friendly +// toH format bytes number friendly func toH(bytes uint64) string { switch { case bytes < 1024: diff --git a/core/bean/doc.go b/core/bean/doc.go index f806a081..049fe563 100644 --- a/core/bean/doc.go +++ b/core/bean/doc.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// bean is a basic package +// Package bean is a basic package // it should not depend on other modules except common module, log module and config module package bean diff --git a/core/bean/mock.go b/core/bean/mock.go index 0a8d3e29..86d90c74 100644 --- a/core/bean/mock.go +++ b/core/bean/mock.go @@ -7,7 +7,7 @@ import ( "strings" ) -// the mock object must be pointer of struct +// Mock have a mock object ,it must be pointer of struct // the element in mock object can be slices, structures, basic data types, pointers and interface func Mock(v interface{}) (err error) { pv := reflect.ValueOf(v) diff --git a/core/berror/error.go b/core/berror/error.go index ca09798a..c40009c6 100644 --- a/core/berror/error.go +++ b/core/berror/error.go @@ -25,7 +25,7 @@ import ( // code, msg const errFmt = "ERROR-%d, %s" -// Err returns an error representing c and msg. If c is OK, returns nil. +// Error returns an error representing c and msg. If c is OK, returns nil. func Error(c Code, msg string) error { return fmt.Errorf(errFmt, c.Code(), msg) } diff --git a/core/config/config.go b/core/config/config.go index 95a4eb26..9e84f059 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -53,20 +53,20 @@ import ( // Configer defines how to get and set value from configuration raw data. type Configer interface { - // support section::key type in given key when using ini type. + // Set support section::key type in given key when using ini type. Set(key, val string) error - // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. + // String support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. String(key string) (string, error) - // get string slice + // Strings get string slice Strings(key string) ([]string, error) Int(key string) (int, error) Int64(key string) (int64, error) Bool(key string) (bool, error) Float(key string) (float64, error) - // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. + // DefaultString support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. DefaultString(key string, defaultVal string) string - // get string slice + // DefaultStrings get string slice DefaultStrings(key string, defaultVal []string) []string DefaultInt(key string, defaultVal int) int DefaultInt64(key string, defaultVal int64) int64 diff --git a/core/config/global.go b/core/config/global.go index 3a334cb6..6f692fce 100644 --- a/core/config/global.go +++ b/core/config/global.go @@ -28,17 +28,17 @@ func InitGlobalInstance(name string, cfg string) error { return err } -// support section::key type in given key when using ini type. +// Set support section::key type in given key when using ini type. func Set(key, val string) error { return globalInstance.Set(key, val) } -// support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. +// String support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. func String(key string) (string, error) { return globalInstance.String(key) } -// get string slice +// Strings will get string slice func Strings(key string) ([]string, error) { return globalInstance.Strings(key) } @@ -59,12 +59,12 @@ func Float(key string) (float64, error) { return globalInstance.Float(key) } -// support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. +// DefaultString support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. func DefaultString(key string, defaultVal string) string { return globalInstance.DefaultString(key, defaultVal) } -// get string slice +// DefaultStrings will get string slice func DefaultStrings(key string, defaultVal []string) []string { return globalInstance.DefaultStrings(key, defaultVal) } diff --git a/core/config/toml/toml.go b/core/config/toml/toml.go index 0c678164..ca4eb74e 100644 --- a/core/config/toml/toml.go +++ b/core/config/toml/toml.go @@ -19,9 +19,8 @@ import ( "os" "strings" - "github.com/pelletier/go-toml" - "github.com/beego/beego/v2/core/config" + "github.com/pelletier/go-toml" ) const keySeparator = "." @@ -135,7 +134,7 @@ func (c *configContainer) Int64(key string) (int64, error) { } } -// bool return bool value +// Bool return bool value // return error if key not found or value is invalid type func (c *configContainer) Bool(key string) (bool, error) { res, err := c.get(key) diff --git a/core/utils/time.go b/core/utils/time.go index 00d13861..2f813a05 100644 --- a/core/utils/time.go +++ b/core/utils/time.go @@ -19,7 +19,7 @@ import ( "time" ) -// short string format +// ToShortTimeFormat short string format func ToShortTimeFormat(d time.Duration) string { u := uint64(d) if u < uint64(time.Second) { diff --git a/go.mod b/go.mod index 24f443b6..6542c5cd 100644 --- a/go.mod +++ b/go.mod @@ -28,17 +28,17 @@ require ( github.com/prometheus/client_golang v1.12.1 github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.8.0 go.etcd.io/etcd/client/v3 v3.5.4 - go.opentelemetry.io/otel v1.7.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 - go.opentelemetry.io/otel/sdk v1.7.0 - go.opentelemetry.io/otel/trace v1.7.0 + go.opentelemetry.io/otel v1.8.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.8.0 + go.opentelemetry.io/otel/sdk v1.8.0 + go.opentelemetry.io/otel/trace v1.8.0 golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a google.golang.org/grpc v1.38.0 google.golang.org/protobuf v1.26.0 gopkg.in/yaml.v2 v2.4.0 - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b + gopkg.in/yaml.v3 v3.0.1 ) require ( diff --git a/go.sum b/go.sum index dacd50c2..d9ce81a6 100644 --- a/go.sum +++ b/go.sum @@ -205,8 +205,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -431,13 +430,15 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112 h1:NBrpnvz0pDPf3+HXZ1C9GcJd1DTpWDLcLWZhNq6uP7o= github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -466,14 +467,14 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 h1:8hPcgCg0rUJiKE6VWahRvjgLUrNl7rW2hffUEPKXVEM= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0/go.mod h1:K4GDXPY6TjUiwbOh+DkKaEdCF8y+lvMoM6SeAPyfCCM= -go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0= -go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= +go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg= +go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.8.0 h1:FVy7BZCjoA2Nk+fHqIdoTmm554J9wTX+YcrDp+mc368= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.8.0/go.mod h1:ztncjvKpotSUQq7rlgPibGt8kZfSI3/jI8EO7JjuY2c= +go.opentelemetry.io/otel/sdk v1.8.0 h1:xwu69/fNuwbSHWe/0PGS888RmjWY181OmcXDQKu7ZQk= +go.opentelemetry.io/otel/sdk v1.8.0/go.mod h1:uPSfc+yfDH2StDM/Rm35WE8gXSNdvCg023J6HeGNO0c= +go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY= +go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= @@ -631,7 +632,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= @@ -701,7 +701,6 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -820,8 +819,9 @@ gopkg.in/yaml.v2 v2.3.0/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 h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 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= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/server/web/admin.go b/server/web/admin.go index 285f7feb..56d2906f 100644 --- a/server/web/admin.go +++ b/server/web/admin.go @@ -16,6 +16,7 @@ package web import ( "fmt" + "net" "net/http" "reflect" "time" @@ -86,7 +87,7 @@ func (admin *adminApp) Run() { " please invoke task.StartTask, or task will not be executed") addr := BConfig.Listen.AdminAddr if BConfig.Listen.AdminPort != 0 { - addr = fmt.Sprintf("%s:%d", BConfig.Listen.AdminAddr, BConfig.Listen.AdminPort) + addr = net.JoinHostPort(BConfig.Listen.AdminAddr, fmt.Sprintf("%d", BConfig.Listen.AdminPort)) } logs.Info("Admin server Running on %s", addr) admin.HttpServer.Run(addr) @@ -102,6 +103,7 @@ func registerAdmin() error { // copy config to avoid conflict adminCfg := *BConfig adminCfg.Listen.EnableHTTPS = false + adminCfg.Listen.EnableMutualHTTPS = false beeAdminApp = &adminApp{ HttpServer: NewHttpServerWithCfg(&adminCfg), } diff --git a/server/web/context/context.go b/server/web/context/context.go index e165527b..c85dc45b 100644 --- a/server/web/context/context.go +++ b/server/web/context/context.go @@ -270,7 +270,7 @@ func (ctx *Context) XSRFToken(key string, expire int64) string { if !ok { token = string(utils.RandomCreateBytes(32)) // TODO make it configurable - ctx.SetSecureCookie(key, "_xsrf", token, expire, "/", "") + ctx.SetSecureCookie(key, "_xsrf", token, expire, "/", "", true, true) } ctx._xsrfToken = token } diff --git a/server/web/grace/server.go b/server/web/grace/server.go index c8a5f840..982849f3 100644 --- a/server/web/grace/server.go +++ b/server/web/grace/server.go @@ -38,6 +38,7 @@ func (srv *Server) Serve() (err error) { } func (srv *Server) ServeWithListener(ln net.Listener) (err error) { + srv.ln = ln go srv.handleSignals() return srv.internalServe(ln) } diff --git a/task/task.go b/task/task.go index 09a08144..7001b9ed 100644 --- a/task/task.go +++ b/task/task.go @@ -465,11 +465,16 @@ func DeleteTask(taskName string) { globalTaskManager.DeleteTask(taskName) } -// ClearTask clear all tasks +// ClearTask clear all tasks func ClearTask() { globalTaskManager.ClearTask() } +// GetAllTasks get all tasks +func GetAllTasks() []Tasker { + return globalTaskManager.GetAllTasks() +} + // GracefulShutdown wait all task done func GracefulShutdown() <-chan struct{} { return globalTaskManager.GracefulShutdown() @@ -635,7 +640,7 @@ func (m *taskManager) DeleteTask(taskname string) { } } -// ClearTask clear all tasks +// ClearTask clear all tasks func (m *taskManager) ClearTask() { isChanged := false @@ -653,6 +658,20 @@ func (m *taskManager) ClearTask() { } } +// GetAllTasks get all tasks +func (m *taskManager) GetAllTasks() []Tasker { + m.taskLock.RLock() + + l := make([]Tasker, 0, len(m.adminTaskList)) + + for _, t := range m.adminTaskList { + l = append(l, t) + } + m.taskLock.RUnlock() + + return l +} + // MapSorter sort map for tasker type MapSorter struct { Keys []string diff --git a/task/task_test.go b/task/task_test.go index 8d274e8f..1fdfd4b9 100644 --- a/task/task_test.go +++ b/task/task_test.go @@ -206,3 +206,24 @@ func wait(wg *sync.WaitGroup) chan bool { }() return ch } + +func TestGetAllTasks(t *testing.T) { + m := newTaskManager() + defer m.ClearTask() + + tk := NewTask("task1", "0/30 * * * * *", func(ctx context.Context) error { + return nil + }) + + tk2 := NewTask("task2", "0/40 * * * * *", func(ctx context.Context) error { + return nil + }) + + m.AddTask("task1", tk) + m.AddTask("task2", tk2) + + tasks := m.GetAllTasks() + total := len(tasks) + + assert.Equal(t, 2, total) +}