Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
SkyAPM
go2sky
提交
fcf44ecd
G
go2sky
项目概览
SkyAPM
/
go2sky
通知
2
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go2sky
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
fcf44ecd
编写于
3月 25, 2019
作者:
G
Gao Hongtao
提交者:
GitHub
3月 25, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Polish segment codes (#2)
上级
a0b15b25
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
114 addition
and
90 deletion
+114
-90
segment.go
segment.go
+103
-0
segment_test.go
segment_test.go
+5
-5
trace.go
trace.go
+6
-85
未找到文件。
segment.go
0 → 100644
浏览文件 @
fcf44ecd
package
go2sky
import
"sync/atomic"
func
newSegmentSpan
(
defaultSpan
*
defaultSpan
,
parentSpan
Span
)
Span
{
s
:=
&
segmentSpanImpl
{
defaultSpan
:
*
defaultSpan
,
segmentContext
:
&
segmentContext
{},
}
if
parentSpan
==
nil
{
return
newSegmentRoot
(
s
)
}
if
rootSpan
,
ok
:=
parentSpan
.
(
segmentSpan
);
ok
{
if
rootSpan
.
segmentRegister
()
{
s
.
segmentContext
=
rootSpan
.
context
()
return
s
}
return
newSegmentRoot
(
s
)
}
return
newSegmentRoot
(
s
)
}
type
segmentSpan
interface
{
context
()
*
segmentContext
segmentRegister
()
bool
}
type
segmentSpanImpl
struct
{
defaultSpan
*
segmentContext
}
func
(
s
*
segmentSpanImpl
)
context
()
*
segmentContext
{
return
s
.
segmentContext
}
type
segmentContext
struct
{
collect
chan
<-
Span
refNum
*
int32
}
func
(
s
*
segmentSpanImpl
)
segmentRegister
()
bool
{
for
{
o
:=
atomic
.
LoadInt32
(
s
.
refNum
)
if
o
<
0
{
return
false
}
if
atomic
.
CompareAndSwapInt32
(
s
.
refNum
,
o
,
o
+
1
)
{
return
true
}
}
}
func
(
s
*
segmentSpanImpl
)
End
()
{
go
func
()
{
s
.
collect
<-
s
}()
}
type
rootSegmentSpan
struct
{
*
segmentSpanImpl
notify
<-
chan
Span
segment
[]
Span
doneCh
chan
int32
}
func
(
rs
*
rootSegmentSpan
)
End
()
{
go
func
()
{
rs
.
doneCh
<-
atomic
.
SwapInt32
(
rs
.
refNum
,
-
1
)
}()
}
func
newSegmentRoot
(
segmentSpan
*
segmentSpanImpl
)
*
rootSegmentSpan
{
s
:=
&
rootSegmentSpan
{
segmentSpanImpl
:
segmentSpan
,
}
var
init
int32
s
.
refNum
=
&
init
ch
:=
make
(
chan
Span
)
s
.
collect
=
ch
s
.
notify
=
ch
s
.
segment
=
make
([]
Span
,
0
,
10
)
s
.
doneCh
=
make
(
chan
int32
)
go
func
()
{
total
:=
-
1
defer
close
(
ch
)
defer
close
(
s
.
doneCh
)
for
{
select
{
case
span
:=
<-
s
.
notify
:
s
.
segment
=
append
(
s
.
segment
,
span
)
case
n
:=
<-
s
.
doneCh
:
total
=
int
(
n
)
}
if
total
==
len
(
s
.
segment
)
{
break
}
}
s
.
tracer
.
reporter
.
Send
(
append
(
s
.
segment
,
s
))
}()
return
s
}
segment_test.go
浏览文件 @
fcf44ecd
...
...
@@ -69,14 +69,14 @@ func TestAsyncMultipleSegments(t *testing.T) {
reportWg
.
Wait
()
reportWg
.
Add
(
2
)
go
func
()
{
oSpan
,
c
tx
,
_
:=
tracer
.
CreateLocalSpan
(
ctx
)
eSpan
,
_
:=
tracer
.
CreateExitSpan
(
c
tx
,
MockInjector
)
oSpan
,
subC
tx
,
_
:=
tracer
.
CreateLocalSpan
(
ctx
)
eSpan
,
_
:=
tracer
.
CreateExitSpan
(
subC
tx
,
MockInjector
)
eSpan
.
End
()
oSpan
.
End
()
}()
go
func
()
{
oSpan
,
c
tx
,
_
:=
tracer
.
CreateLocalSpan
(
ctx
)
eSpan
,
_
:=
tracer
.
CreateExitSpan
(
c
tx
,
MockInjector
)
oSpan
,
subC
tx
,
_
:=
tracer
.
CreateLocalSpan
(
ctx
)
eSpan
,
_
:=
tracer
.
CreateExitSpan
(
subC
tx
,
MockInjector
)
eSpan
.
End
()
oSpan
.
End
()
}()
...
...
@@ -116,7 +116,7 @@ func (r *MockReporter) Verify(mm ...int) error {
}
for
i
,
m
:=
range
mm
{
if
m
!=
len
(
r
.
Message
[
i
])
{
return
fmt
.
Errorf
(
"span size mismatch. expected %d actual %d"
,
len
(
mm
),
len
(
r
.
Message
))
return
fmt
.
Errorf
(
"span size mismatch. expected %d actual %d"
,
m
,
len
(
r
.
Message
[
i
]
))
}
}
return
nil
...
...
trace.go
浏览文件 @
fcf44ecd
...
...
@@ -2,8 +2,6 @@ package go2sky
import
(
"context"
"sync/atomic"
"github.com/tetratelabs/go2sky/propagation"
)
...
...
@@ -36,27 +34,18 @@ func (t *Tracer) CreateEntrySpan(ctx context.Context, extractor propagation.Extr
}
// CreateLocalSpan creates and starts a span for local usage
func
(
t
*
Tracer
)
CreateLocalSpan
(
ctx
context
.
Context
,
opts
...
SpanOption
)
(
Span
,
context
.
Context
,
error
)
{
root
:=
true
if
parentSpan
,
ok
:=
ctx
.
Value
(
key
)
.
(
Span
);
ok
&&
parentSpan
!=
nil
{
func
(
t
*
Tracer
)
CreateLocalSpan
(
ctx
context
.
Context
,
opts
...
SpanOption
)
(
s
Span
,
c
context
.
Context
,
err
error
)
{
parentSpan
,
ok
:=
ctx
.
Value
(
key
)
.
(
Span
)
if
ok
&&
parentSpan
!=
nil
{
opts
=
append
(
opts
,
WithParent
(
parentSpan
.
Context
()))
if
parentRootSpan
,
okk
:=
parentSpan
.
(
SegmentSpan
);
okk
{
root
=
!
parentRootSpan
.
SegmentRegister
()
opts
=
append
(
opts
,
func
(
s
*
defaultSpan
)
{
s
.
segmentContext
=
parentRootSpan
.
SegmentContext
()
})
}
}
s
:=
&
defaultSpan
{
d
s
:=
&
defaultSpan
{
tracer
:
t
,
root
:
root
,
}
for
_
,
opt
:=
range
opts
{
opt
(
s
)
}
if
root
{
s
.
createSegment
()
opt
(
ds
)
}
s
=
newSegmentSpan
(
ds
,
parentSpan
)
return
s
,
context
.
WithValue
(
ctx
,
key
,
s
),
nil
}
...
...
@@ -80,85 +69,17 @@ type Span interface {
End
()
}
// SegmentSpan interface as segment span specification
type
SegmentSpan
interface
{
SegmentRegister
()
bool
SegmentContext
()
segmentContext
}
type
defaultSpan
struct
{
propagation
.
ContextCarrier
segmentContext
root
bool
notify
<-
chan
Span
segment
[]
Span
doneCh
chan
int32
tracer
*
Tracer
}
type
segmentContext
struct
{
collect
chan
<-
Span
refNum
*
int32
}
func
(
s
*
defaultSpan
)
Context
()
propagation
.
ContextCarrier
{
return
s
.
ContextCarrier
}
func
(
s
*
defaultSpan
)
SegmentRegister
()
bool
{
for
{
o
:=
atomic
.
LoadInt32
(
s
.
refNum
)
if
o
<
0
{
return
false
}
if
atomic
.
CompareAndSwapInt32
(
s
.
refNum
,
o
,
o
+
1
)
{
return
true
}
}
}
func
(
s
*
defaultSpan
)
SegmentContext
()
segmentContext
{
return
s
.
segmentContext
}
func
(
s
*
defaultSpan
)
End
()
{
go
func
()
{
if
s
.
root
{
s
.
doneCh
<-
atomic
.
SwapInt32
(
s
.
refNum
,
-
1
)
return
}
s
.
collect
<-
s
}()
}
func
(
s
*
defaultSpan
)
createSegment
()
{
var
init
int32
s
.
refNum
=
&
init
ch
:=
make
(
chan
Span
)
s
.
collect
=
ch
s
.
notify
=
ch
s
.
segment
=
make
([]
Span
,
0
,
10
)
s
.
doneCh
=
make
(
chan
int32
)
go
func
()
{
total
:=
-
1
defer
close
(
ch
)
defer
close
(
s
.
doneCh
)
for
{
select
{
case
span
,
ok
:=
<-
s
.
notify
:
if
!
ok
{
return
}
s
.
segment
=
append
(
s
.
segment
,
span
)
case
n
:=
<-
s
.
doneCh
:
total
=
int
(
n
)
}
if
total
==
len
(
s
.
segment
)
{
break
}
}
s
.
tracer
.
reporter
.
Send
(
append
(
s
.
segment
,
s
))
}()
}
// SpanOption allows for functional options to adjust behaviour
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录