Skip to content

Commit

Permalink
Merge branch 'zeromicro:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ch3nnn authored Mar 1, 2024
2 parents c90424e + ec41880 commit adeaf74
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 9 deletions.
9 changes: 8 additions & 1 deletion core/errorx/batcherror.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package errorx

import "bytes"
import (
"bytes"
"sync"
)

type (
// A BatchError is an error that can hold multiple errors.
BatchError struct {
mu sync.Mutex
errs errorArray
}

Expand All @@ -13,6 +17,9 @@ type (

// Add adds errs to be, nil errors are ignored.
func (be *BatchError) Add(errs ...error) {
be.mu.Lock()
defer be.mu.Unlock()

for _, err := range errs {
if err != nil {
be.errs = append(be.errs, err)
Expand Down
24 changes: 22 additions & 2 deletions core/errorx/batcherror_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package errorx
import (
"errors"
"fmt"
"sync"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -33,7 +34,7 @@ func TestBatchErrorNilFromFunc(t *testing.T) {
func TestBatchErrorOneError(t *testing.T) {
var batch BatchError
batch.Add(errors.New(err1))
assert.NotNil(t, batch)
assert.NotNil(t, batch.Err())
assert.Equal(t, err1, batch.Err().Error())
assert.True(t, batch.NotNil())
}
Expand All @@ -42,7 +43,26 @@ func TestBatchErrorWithErrors(t *testing.T) {
var batch BatchError
batch.Add(errors.New(err1))
batch.Add(errors.New(err2))
assert.NotNil(t, batch)
assert.NotNil(t, batch.Err())
assert.Equal(t, fmt.Sprintf("%s\n%s", err1, err2), batch.Err().Error())
assert.True(t, batch.NotNil())
}

func TestBatchErrorConcurrentAdd(t *testing.T) {
const count = 10000
var batch BatchError
var wg sync.WaitGroup

wg.Add(count)
for i := 0; i < count; i++ {
go func() {
defer wg.Done()
batch.Add(errors.New(err1))
}()
}
wg.Wait()

assert.NotNil(t, batch.Err())
assert.Equal(t, count, len(batch.errs))
assert.True(t, batch.NotNil())
}
8 changes: 8 additions & 0 deletions core/stat/internal/cpu_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ var (
preTotal uint64
limit float64
cores uint64
noCgroup bool
initOnce sync.Once
)

// if /proc not present, ignore the cpu calculation, like wsl linux
func initialize() {
cpus, err := effectiveCpus()
if err != nil {
noCgroup = true
logx.Error(err)
return
}
Expand All @@ -45,12 +47,14 @@ func initialize() {

preSystem, err = systemCpuUsage()
if err != nil {
noCgroup = true
logx.Error(err)
return
}

preTotal, err = cpuUsage()
if err != nil {
noCgroup = true
logx.Error(err)
return
}
Expand All @@ -60,6 +64,10 @@ func initialize() {
func RefreshCpu() uint64 {
initOnce.Do(initialize)

if noCgroup {
return 0
}

total, err := cpuUsage()
if err != nil {
return 0
Expand Down
11 changes: 10 additions & 1 deletion core/stores/sqlx/stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sqlx
import (
"context"
"database/sql"
"errors"
"time"

"github.com/zeromicro/go-zero/core/breaker"
Expand Down Expand Up @@ -70,6 +71,9 @@ func (s statement) ExecCtx(ctx context.Context, args ...any) (result sql.Result,
}, func(err error) bool {
return s.accept(err)
})
if errors.Is(err, breaker.ErrServiceUnavailable) {
metricReqErr.Inc("stmt_exec", "breaker")
}

return
}
Expand Down Expand Up @@ -137,7 +141,7 @@ func (s statement) QueryRowsPartialCtx(ctx context.Context, v any, args ...any)
func (s statement) queryRows(ctx context.Context, scanFn func(any, rowsScanner) error,
v any, args ...any) error {
var scanFailed bool
return s.brk.DoWithAcceptable(func() error {
err := s.brk.DoWithAcceptable(func() error {
return queryStmt(ctx, s.stmt, func(rows *sql.Rows) error {
err := scanFn(v, rows)
if err != nil {
Expand All @@ -148,6 +152,11 @@ func (s statement) queryRows(ctx context.Context, scanFn func(any, rowsScanner)
}, func(err error) bool {
return scanFailed || s.accept(err)
})
if errors.Is(err, breaker.ErrServiceUnavailable) {
metricReqErr.Inc("stmt_queryRows", "breaker")
}

return err
}

// DisableLog disables logging of sql statements, includes info and slow logs.
Expand Down
48 changes: 47 additions & 1 deletion core/stores/sqlx/stmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func TestNilGuard(t *testing.T) {
assert.Equal(t, nilGuard{}, guard)
}

func TestStmtScanFailed(t *testing.T) {
func TestStmtBreaker(t *testing.T) {
dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
mock.ExpectPrepare("any")

Expand All @@ -242,6 +242,52 @@ func TestStmtScanFailed(t *testing.T) {
assert.NotErrorIs(t, err, breaker.ErrServiceUnavailable)
}
})

dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
mock.ExpectPrepare("any")
conn := NewSqlConnFromDB(db)
stmt, err := conn.Prepare("any")
assert.NoError(t, err)

for i := 0; i < 1000; i++ {
assert.Error(t, conn.Transact(func(session Session) error {
return nil
}))
}

var breakerTriggered bool
for i := 0; i < 1000; i++ {
_, err = stmt.Exec("any")
if errors.Is(err, breaker.ErrServiceUnavailable) {
breakerTriggered = true
break
}
}
assert.True(t, breakerTriggered)
})

dbtest.RunTest(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
mock.ExpectPrepare("any")
conn := NewSqlConnFromDB(db)
stmt, err := conn.Prepare("any")
assert.NoError(t, err)

for i := 0; i < 1000; i++ {
assert.Error(t, conn.Transact(func(session Session) error {
return nil
}))
}

var breakerTriggered bool
for i := 0; i < 1000; i++ {
err = stmt.QueryRows(&struct{}{}, "any")
if errors.Is(err, breaker.ErrServiceUnavailable) {
breakerTriggered = true
break
}
}
assert.True(t, breakerTriggered)
})
}

type mockedSessionConn struct {
Expand Down
4 changes: 2 additions & 2 deletions readme-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ go-zero 已被许多公司用于生产部署,接入场景如在线教育、电
## 10. CNCF 云原生技术全景图

<p float="left">
<img src="https://landscape.cncf.io/images/left-logo.svg" width="150"/>&nbsp;&nbsp;&nbsp;
<img src="https://landscape.cncf.io/images/right-logo.svg" width="200"/>
<img src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/cncf-logo.svg" width="200"/>&nbsp;&nbsp;&nbsp;
<img src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/cncf-landscape-logo.svg" width="150"/>
</p>

go-zero 收录在 [CNCF Cloud Native 云原生技术全景图](https://landscape.cncf.io/?selected=go-zero)。
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ Join the chat via https://discord.gg/4JQvC5A4Fe
## Cloud Native Landscape

<p float="left">
<img src="https://landscape.cncf.io/images/left-logo.svg" width="150"/>&nbsp;&nbsp;&nbsp;
<img src="https://landscape.cncf.io/images/right-logo.svg" width="200"/>
<img src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/cncf-logo.svg" width="200"/>&nbsp;&nbsp;&nbsp;
<img src="https://raw.githubusercontent.com/zeromicro/zero-doc/main/doc/images/cncf-landscape-logo.svg" width="150"/>
</p>

go-zero enlisted in the [CNCF Cloud Native Landscape](https://landscape.cncf.io/?selected=go-zero).
Expand Down

0 comments on commit adeaf74

Please sign in to comment.