Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
go-ipfs
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
jihao
go-ipfs
Commits
42e6e547
提交
42e6e547
authored
11月 21, 2016
作者:
Jeromy
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cleanup bitswap and handle message send failure slightly better
License: MIT Signed-off-by:
Jeromy
<
why@ipfs.io
>
上级
116aab77
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
88 行增加
和
49 行删除
+88
-49
bitswap.go
exchange/bitswap/bitswap.go
+18
-18
wantmanager.go
exchange/bitswap/wantmanager.go
+64
-31
workers.go
exchange/bitswap/workers.go
+6
-0
没有找到文件。
exchange/bitswap/bitswap.go
浏览文件 @
42e6e547
...
...
@@ -82,7 +82,6 @@ func New(parent context.Context, p peer.ID, network bsnet.BitSwapNetwork,
})
bs
:=
&
Bitswap
{
self
:
p
,
blockstore
:
bstore
,
notifications
:
notif
,
engine
:
decision
.
NewEngine
(
ctx
,
bstore
),
// TODO close the engine with Close() method
...
...
@@ -112,34 +111,36 @@ func New(parent context.Context, p peer.ID, network bsnet.BitSwapNetwork,
// Bitswap instances implement the bitswap protocol.
type
Bitswap
struct
{
// the peermanager manages sending messages to peers in a way that
// wont block bitswap operation
wm
*
WantManager
// the
ID of the peer to act on behalf of
self
peer
.
ID
// the
engine is the bit of logic that decides who to send which blocks to
engine
*
decision
.
Engine
// network delivers messages on behalf of the session
network
bsnet
.
BitSwapNetwork
// the peermanager manages sending messages to peers in a way that
// wont block bitswap operation
wm
*
WantManager
// blockstore is the local database
// NB: ensure threadsafety
blockstore
blockstore
.
Blockstore
// notifications engine for receiving new blocks and routing them to the
// appropriate user requests
notifications
notifications
.
PubSub
//
send
keys to a worker to find and connect to providers for them
//
findKeys sends
keys to a worker to find and connect to providers for them
findKeys
chan
*
blockRequest
engine
*
decision
.
Engine
process
process
.
Process
// newBlocks is a channel for newly added blocks to be provided to the
// network. blocks pushed down this channel get buffered and fed to the
// provideKeys channel later on to avoid too much network activity
newBlocks
chan
*
cid
.
Cid
// provideKeys directly feeds provide workers
provideKeys
chan
*
cid
.
Cid
process
process
.
Process
// Counters for various statistics
counterLk
sync
.
Mutex
blocksRecvd
int
dupBlocksRecvd
int
...
...
@@ -167,13 +168,12 @@ func (bs *Bitswap) GetBlock(parent context.Context, k *cid.Cid) (blocks.Block, e
// enforce. May this comment keep you safe.
ctx
,
cancelFunc
:=
context
.
WithCancel
(
parent
)
// TODO: this request ID should come in from a higher layer so we can track
// across multiple 'GetBlock' invocations
ctx
=
logging
.
ContextWithLoggable
(
ctx
,
loggables
.
Uuid
(
"GetBlockRequest"
))
log
.
Event
(
ctx
,
"Bitswap.GetBlockRequest.Start"
,
k
)
defer
log
.
Event
(
ctx
,
"Bitswap.GetBlockRequest.End"
,
k
)
defer
func
()
{
cancelFunc
()
}()
defer
cancelFunc
()
promise
,
err
:=
bs
.
GetBlocks
(
ctx
,
[]
*
cid
.
Cid
{
k
})
if
err
!=
nil
{
...
...
exchange/bitswap/wantmanager.go
浏览文件 @
42e6e547
...
...
@@ -175,28 +175,13 @@ func (mq *msgQueue) runQueue(ctx context.Context) {
}
func
(
mq
*
msgQueue
)
doWork
(
ctx
context
.
Context
)
{
// allow ten minutes for connections
// this includes looking them up in the dht
// dialing them, and handshaking
if
mq
.
sender
==
nil
{
conctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Minute
*
10
)
defer
cancel
()
err
:=
mq
.
network
.
ConnectTo
(
conctx
,
mq
.
p
)
err
:=
mq
.
openSender
(
ctx
)
if
err
!=
nil
{
log
.
Infof
(
"cant
connect
to peer %s: %s"
,
mq
.
p
,
err
)
log
.
Infof
(
"cant
open message sender
to peer %s: %s"
,
mq
.
p
,
err
)
// TODO: cant connect, what now?
return
}
nsender
,
err
:=
mq
.
network
.
NewMessageSender
(
ctx
,
mq
.
p
)
if
err
!=
nil
{
log
.
Infof
(
"cant open new stream to peer %s: %s"
,
mq
.
p
,
err
)
// TODO: cant open stream, what now?
return
}
mq
.
sender
=
nsender
}
// grab outgoing message
...
...
@@ -210,14 +195,64 @@ func (mq *msgQueue) doWork(ctx context.Context) {
mq
.
outlk
.
Unlock
()
// send wantlist updates
err
:=
mq
.
sender
.
SendMsg
(
wlm
)
if
err
!=
nil
{
for
{
// try to send this message until we fail.
err
:=
mq
.
sender
.
SendMsg
(
wlm
)
if
err
==
nil
{
return
}
log
.
Infof
(
"bitswap send error: %s"
,
err
)
mq
.
sender
.
Close
()
mq
.
sender
=
nil
// TODO: what do we do if this fails?
return
select
{
case
<-
mq
.
done
:
return
case
<-
ctx
.
Done
()
:
return
case
<-
time
.
After
(
time
.
Millisecond
*
100
)
:
// wait 100ms in case disconnect notifications are still propogating
log
.
Warning
(
"SendMsg errored but neither 'done' nor context.Done() were set"
)
}
err
=
mq
.
openSender
(
ctx
)
if
err
!=
nil
{
log
.
Error
(
"couldnt open sender again after SendMsg(%s) failed: %s"
,
mq
.
p
,
err
)
// TODO(why): what do we do now?
// I think the *right* answer is to probably put the message we're
// trying to send back, and then return to waiting for new work or
// a disconnect.
return
}
// TODO: Is this the same instance for the remote peer?
// If its not, we should resend our entire wantlist to them
/*
if mq.sender.InstanceID() != mq.lastSeenInstanceID {
wlm = mq.getFullWantlistMessage()
}
*/
}
}
func
(
mq
*
msgQueue
)
openSender
(
ctx
context
.
Context
)
error
{
// allow ten minutes for connections this includes looking them up in the
// dht dialing them, and handshaking
conctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
time
.
Minute
*
10
)
defer
cancel
()
err
:=
mq
.
network
.
ConnectTo
(
conctx
,
mq
.
p
)
if
err
!=
nil
{
return
err
}
nsender
,
err
:=
mq
.
network
.
NewMessageSender
(
ctx
,
mq
.
p
)
if
err
!=
nil
{
return
err
}
mq
.
sender
=
nsender
return
nil
}
func
(
pm
*
WantManager
)
Connected
(
p
peer
.
ID
)
{
...
...
@@ -292,14 +327,13 @@ func (pm *WantManager) Run() {
}
func
(
wm
*
WantManager
)
newMsgQueue
(
p
peer
.
ID
)
*
msgQueue
{
mq
:=
new
(
msgQueue
)
mq
.
done
=
make
(
chan
struct
{})
mq
.
work
=
make
(
chan
struct
{},
1
)
mq
.
network
=
wm
.
network
mq
.
p
=
p
mq
.
refcnt
=
1
return
mq
return
&
msgQueue
{
done
:
make
(
chan
struct
{}),
work
:
make
(
chan
struct
{},
1
),
network
:
wm
.
network
,
p
:
p
,
refcnt
:
1
,
}
}
func
(
mq
*
msgQueue
)
addMessage
(
entries
[]
*
bsmsg
.
Entry
)
{
...
...
@@ -312,8 +346,7 @@ func (mq *msgQueue) addMessage(entries []*bsmsg.Entry) {
}
}()
// if we have no message held, or the one we are given is full
// overwrite the one we are holding
// if we have no message held allocate a new one
if
mq
.
out
==
nil
{
mq
.
out
=
bsmsg
.
New
(
false
)
}
...
...
exchange/bitswap/workers.go
浏览文件 @
42e6e547
...
...
@@ -197,6 +197,12 @@ func (bs *Bitswap) providerQueryManager(ctx context.Context) {
for
{
select
{
case
e
:=
<-
bs
.
findKeys
:
select
{
// make sure its not already cancelled
case
<-
e
.
Ctx
.
Done
()
:
continue
default
:
}
activeLk
.
Lock
()
if
kset
.
Has
(
e
.
Cid
)
{
activeLk
.
Unlock
()
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论