Skip to content

Commit

Permalink
fix: add stress test for aop (#109)
Browse files Browse the repository at this point in the history
* fix: add stress test for aop

* fix: ut

* Fix: ut

* fix: Add release makefile and git ignore for iocli.

* fix: ut

* Fix: add release script

* Fix: fix tar
  • Loading branch information
LaurenceLiZhixin authored Jul 27, 2022
1 parent a8481c6 commit 278a4e6
Show file tree
Hide file tree
Showing 25 changed files with 530 additions and 171 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
*.DS_Store
.idea
.idea
iocli/.release
.release
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@ test-all:
go test ./... -cover -p 1
cd extension && go test ./... -cover -p 1
cd example && go test ./... -cover -p 1
cd iocli && go test ./... -cover -p 1
cd iocli && go test ./... -cover -p 1

release-all: gen-all test-all
mkdir -p .release/ioc-golang
cd iocli && make build-all-platform && mv ./.release ../.release/iocli
cp -r `ls` ./.release/ioc-golang
tar -czvf ./.release/ioc-golang.tar.gz ./.release/ioc-golang
7 changes: 5 additions & 2 deletions aop/common/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func CurrentCallingMethodName(skip int) string {
return runtime.FuncForPC(pc[0]).Name()
}

func TraceLevel(entranceName string) int64 {
func IsTraceEntrance(entranceName string) bool {
pc := make([]uintptr, 500)
n := runtime.Callers(0, pc)
foundEntrance := false
Expand All @@ -42,12 +42,15 @@ func TraceLevel(entranceName string) int64 {
if strings.HasPrefix(fName, ProxyMethodPrefix) {
level++
}
if level == 2 {
return false
}
continue
}
if fName == entranceName {
foundEntrance = true
}
}

return level - 1
return level-1 == 0
}
4 changes: 2 additions & 2 deletions aop/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ func makeProxyFunction(proxyPtr interface{}, rf reflect.Value, sdid, methodName
proxyFunc := func(in []reflect.Value) []reflect.Value {
defer func() {
if r := recover(); r != nil {
logger.Red("[AOP Proxy] Cache error = %s", r)
logger.Red("[AOP Proxy] Catch error = %s", r)
}
}()

invocationCtx := NewInvocationContext(proxyPtr, sdid, methodName, common.CurrentCallingMethodName(4), in)
invocationCtx := NewInvocationContext(proxyPtr, sdid, methodName, common.CurrentCallingMethodName(3), in)

for _, i := range interceptorImpls {
i.BeforeInvoke(invocationCtx)
Expand Down
51 changes: 0 additions & 51 deletions autowire/monkey_test.go

This file was deleted.

13 changes: 4 additions & 9 deletions autowire/wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
package autowire

import (
"os"
"fmt"
"reflect"
"runtime"

perrors "github.com/pkg/errors"

Expand Down Expand Up @@ -168,9 +167,10 @@ func (w *WrapperAutowireImpl) inject(impledPtr interface{}, sdId string) error {
tagKey = aw.TagKey()
tagValue = val
if !(subService.IsValid() && subService.CanSet()) {
err := perrors.Errorf("Failed to autowire struct %s's impl %s service. It's field %s with tag '%s:\"%s\"', please check if the field is exported",
errMsg := fmt.Sprintf("Failed to autowire struct %s's impl %s service. It's field type %s with tag '%s:\"%s\"', please check if the field name is exported",
sd.ID(), util.GetStructName(impledPtr), field.Type.Name(), tagKey, tagValue)
return err
logger.Red("[Autowire Wrapper] Inject field failed with error: %s", errMsg)
return perrors.New(errMsg)
}

fieldType := buildFiledTypeFullName(field.Type)
Expand Down Expand Up @@ -198,11 +198,6 @@ func (w *WrapperAutowireImpl) inject(impledPtr interface{}, sdId string) error {
// set field
subService.Set(reflect.ValueOf(subImpledPtr))
}
// 3. monkey
if monkeyFunction := GetMonkeyFunction(); (os.Getenv("GOARCH") == "amd64" || runtime.GOARCH == "amd64") && monkeyFunction != nil {
// only amd64-os/amd64-go-arch-env with build flags '-gcflags="-N -l" -tags iocdebug' can inject monkey function
monkeyFunction(impledPtr, sd.ID())
}
return nil
}

Expand Down
20 changes: 20 additions & 0 deletions example/aop/observability/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,24 @@ Param 1: (string) (len=8) "laurence"
github.com/alibaba/ioc-golang/example/aop/observability.ServiceImpl1.GetHelloString()
Response 1: (string) (len=36) "This is ServiceImpl2, hello laurence"`))

output, err = iocli_command.Run([]string{"monitor", "-i", "3"}, time.Second*4)
assert.Nil(t, err)
assert.True(t, strings.Contains(output, `github.com/alibaba/ioc-golang/example/aop/observability.ServiceImpl1.GetHelloString()
Total: 1, Success: 1, Fail: 0, AvgRT: `))
assert.True(t, strings.Contains(output, `us, FailRate: 0.00%
github.com/alibaba/ioc-golang/example/aop/observability.ServiceImpl2.GetHelloString()
Total: 1, Success: 1, Fail: 0, AvgRT: `))

output, err = iocli_command.Run([]string{"trace", "github.com/alibaba/ioc-golang/example/aop/observability.ServiceImpl1", "GetHelloString"}, time.Second*6)
assert.Nil(t, err)
assert.True(t, strings.Contains(output, `OperationName: github.com/alibaba/ioc-golang/example/aop/observability.(*serviceImpl2_).GetHelloString, StartTime: `))
assert.True(t, strings.Contains(output, `OperationName: github.com/alibaba/ioc-golang/example/aop/observability.(*serviceImpl1_).GetHelloString, StartTime: `))
assert.True(t, strings.Contains(output, `ReferenceSpans: [{TraceID:`))

output, err = iocli_command.Run([]string{"trace", "github.com/alibaba/ioc-golang/example/aop/observability.ServiceImpl2", "GetHelloString"}, time.Second*6)
assert.Nil(t, err)
assert.True(t, strings.Contains(output, `OperationName: github.com/alibaba/ioc-golang/example/aop/observability.(*serviceImpl2_).GetHelloString, StartTime: `))
assert.True(t, !strings.Contains(output, `OperationName: github.com/alibaba/ioc-golang/example/aop/observability.(*serviceImpl1_).GetHelloString, StartTime: `))
assert.True(t, strings.Contains(output, `ReferenceSpans: [{TraceID:`))

}
2 changes: 1 addition & 1 deletion example/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/alibaba/ioc-golang/example
go 1.17

require (
github.com/alibaba/ioc-golang v0.0.0-20220726064435-a135d55b94e9
github.com/alibaba/ioc-golang v0.0.0-20220726180817-a8481c622579
github.com/alibaba/ioc-golang/extension v0.0.0-20220707071909-d19576eea84e
github.com/apache/rocketmq-client-go/v2 v2.1.0
github.com/go-redis/redis v6.15.9+incompatible
Expand Down
2 changes: 1 addition & 1 deletion extension/aop/trace/goroutine.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (g *goRoutineTraceInterceptor) AfterInvoke(ctx *aop.InvocationContext) {
currentSpan.LogFields(log.String(traceCommon.SpanReturnValuesKey, common.ReflectValues2String(ctx.ReturnValues, int(traceCtx.maxDepth), int(traceCtx.maxLength))))

// calculate level
if common.TraceLevel(traceCtx.getTrace().entranceMethod) == 0 {
if common.IsTraceEntrance(traceCtx.getTrace().entranceMethod) {
// tracing finished
g.tracingGrIDMap.Delete(ctx.GrID)
}
Expand Down
6 changes: 4 additions & 2 deletions extension/aop/trace/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"github.com/alibaba/ioc-golang/logger"
)

const outBatchBufferAndChSize = 1000

type traceServiceImpl struct {
tracePB.UnimplementedTraceServiceServer
traceInterceptor *methodTraceInterceptor
Expand Down Expand Up @@ -57,7 +59,7 @@ func (d *traceServiceImpl) Trace(req *tracePB.TraceRequest, traceServer tracePB.

if req.GetPushToCollectorAddress() != "" {
// start subscribing batch buffer
outBatchBuffer := make(chan *bytes.Buffer, 100)
outBatchBuffer := make(chan *bytes.Buffer, outBatchBufferAndChSize)
getGlobalTracer().subscribeBatchBuffer(outBatchBuffer)
go func() {
for {
Expand All @@ -74,7 +76,7 @@ func (d *traceServiceImpl) Trace(req *tracePB.TraceRequest, traceServer tracePB.
}()
}

outTraceCh := make(chan []*model.Trace, 100)
outTraceCh := make(chan []*model.Trace, outBatchBufferAndChSize)
// start subscribing traces info
getGlobalTracer().subscribeTrace(outTraceCh)
go func() {
Expand Down
9 changes: 6 additions & 3 deletions extension/aop/trace/transport/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import (
)

const memoryStorageType = "memory"
const memoryMaxTraces = 1000
const dynamicQueueMaxMemory = 1 * 1024 * 1024 // 1MB
const queueSize = 1000

type collector struct {
spanHandlers *app.SpanHandlers
Expand All @@ -45,7 +48,7 @@ type collector struct {
func newCollector(appName string, interval int, out chan []*model.Trace) (*collector, error) {
logger := zap.NewNop()
v := viper.New()
v.Set("memory.max-traces", 100)
v.Set("memory.max-traces", memoryMaxTraces)

storageFactory, err := storage.NewFactory(storage.FactoryConfig{
SpanWriterTypes: []string{memoryStorageType},
Expand All @@ -69,8 +72,8 @@ func newCollector(appName string, interval int, out chan []*model.Trace) (*colle
if err != nil {
return nil, err
}
collectorOpts.DynQueueSizeMemory = 1 * 1024 * 1024 // 1MB
collectorOpts.QueueSize = 10
collectorOpts.DynQueueSizeMemory = dynamicQueueMaxMemory
collectorOpts.QueueSize = queueSize

handlerBuilder := &app.SpanHandlerBuilder{
SpanWriter: spanWriter,
Expand Down
6 changes: 3 additions & 3 deletions extension/aop/transaction/interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ func (t *interceptorImpl) AfterInvoke(ctx *aop.InvocationContext) {
// if invocation failed
invocationFailed, err := common.IsInvocationFailed(ctx.ReturnValues)

// 1.1 if current invocation is the entrance of transaction ?
// calculate level
if common.TraceLevel(txCtx.getEntranceMethod()) == 0 {
// if current invocation is the entrance of transaction ?
// check if is entrance
if common.IsTraceEntrance(txCtx.getEntranceMethod()) {
// current invocation is the entrance of transaction
t.transactionGrIDMap.Delete(ctx.GrID)
// if the transaction failed ?
Expand Down
10 changes: 7 additions & 3 deletions extension/aop/watch/aop.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ import (
watchPB "github.com/alibaba/ioc-golang/extension/aop/watch/api/ioc_golang/aop/watch"
)

const Name = "watch"

func init() {
aop.RegisterAOP(aop.AOP{
Name: "watch",
Name: Name,
InterceptorFactory: func() aop.Interceptor {
return getWatchInterceptorSingleton()
impl, _ := GetinterceptorImplIOCInterfaceSingleton()
return impl
},
GRPCServiceRegister: func(server *grpc.Server) {
watchPB.RegisterWatchServiceServer(server, getWatchService())
watchInterface, _ := GetwatchServiceSingleton()
watchPB.RegisterWatchServiceServer(server, watchInterface)
},
})
}
Loading

0 comments on commit 278a4e6

Please sign in to comment.