6
6
inflect "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/chuckpreslar/inflect"
7
7
process "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess"
8
8
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
9
+ u "github.com/jbenet/go-ipfs/util"
9
10
)
10
11
11
12
func (bs * Bitswap ) startWorkers (px process.Process , ctx context.Context ) {
@@ -24,6 +25,10 @@ func (bs *Bitswap) startWorkers(px process.Process, ctx context.Context) {
24
25
bs .rebroadcastWorker (ctx )
25
26
})
26
27
28
+ px .Go (func (px process.Process ) {
29
+ bs .provideCollector (ctx )
30
+ })
31
+
27
32
// Spawn up multiple workers to handle incoming blocks
28
33
// consider increasing number if providing blocks bottlenecks
29
34
// file transfers
@@ -58,13 +63,13 @@ func (bs *Bitswap) taskWorker(ctx context.Context) {
58
63
func (bs * Bitswap ) provideWorker (ctx context.Context ) {
59
64
for {
60
65
select {
61
- case blk , ok := <- bs .newBlocks :
66
+ case k , ok := <- bs .provideKeys :
62
67
if ! ok {
63
- log .Debug ("newBlocks channel closed" )
68
+ log .Debug ("provideKeys channel closed" )
64
69
return
65
70
}
66
71
ctx , _ := context .WithTimeout (ctx , provideTimeout )
67
- err := bs .network .Provide (ctx , blk . Key () )
72
+ err := bs .network .Provide (ctx , k )
68
73
if err != nil {
69
74
log .Error (err )
70
75
}
@@ -74,6 +79,38 @@ func (bs *Bitswap) provideWorker(ctx context.Context) {
74
79
}
75
80
}
76
81
82
+ func (bs * Bitswap ) provideCollector (ctx context.Context ) {
83
+ defer close (bs .provideKeys )
84
+ var toProvide []u.Key
85
+ var nextKey u.Key
86
+ var keysOut chan u.Key
87
+
88
+ for {
89
+ select {
90
+ case blk , ok := <- bs .newBlocks :
91
+ if ! ok {
92
+ log .Debug ("newBlocks channel closed" )
93
+ return
94
+ }
95
+ if keysOut == nil {
96
+ nextKey = blk .Key ()
97
+ keysOut = bs .provideKeys
98
+ } else {
99
+ toProvide = append (toProvide , blk .Key ())
100
+ }
101
+ case keysOut <- nextKey :
102
+ if len (toProvide ) > 0 {
103
+ nextKey = toProvide [0 ]
104
+ toProvide = toProvide [1 :]
105
+ } else {
106
+ keysOut = nil
107
+ }
108
+ case <- ctx .Done ():
109
+ return
110
+ }
111
+ }
112
+ }
113
+
77
114
// TODO ensure only one active request per key
78
115
func (bs * Bitswap ) clientWorker (parent context.Context ) {
79
116
defer log .Info ("bitswap client worker shutting down..." )
0 commit comments