datastore: blockstore should retry when it encounters temp errors
License: MIT Signed-off-by: Jeromy <why@ipfs.io>
Jeromy committed
Aug 16, 2016 at 11:43 UTC
881300804605a1afc867aee818a1b3df0fae272a
4 files changed
+41
-17
core/builder.go
+23
-3
@@ -4,6 +4,9 @@ import (
4
"crypto/rand"
5
"encoding/base64"
6
"errors"
7
+ "os"
8
+ "syscall"
9
+ "time"
10
11
bstore "github.com/ipfs/go-ipfs/blocks/blockstore"
12
key "github.com/ipfs/go-ipfs/blocks/key"
@@ -14,12 +17,13 @@ import (
17
pin "github.com/ipfs/go-ipfs/pin"
18
repo "github.com/ipfs/go-ipfs/repo"
19
cfg "github.com/ipfs/go-ipfs/repo/config"
17
- ds "gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore"
18
- dsync "gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore/sync"
20
21
pstore "gx/ipfs/QmQdnfvZQuhdT93LNc5bos52wAmdr3G2p6G8teLJMEN32P/go-libp2p-peerstore"
22
goprocessctx "gx/ipfs/QmQopLATEYMNg7dVqZRNDfeE2S1yKy8zrRh5xnYiuqeZBn/goprocess/context"
23
+ ds "gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore"
24
+ dsync "gx/ipfs/QmTxLSvdhwg68WJimdS6icLPhZi28aTp6b7uihC2Yb47Xk/go-datastore/sync"
25
ci "gx/ipfs/QmUWER4r4qMvaCnX5zREcfyiWN7cXN9g3a7fkRqNz8qWPP/go-libp2p-crypto"
26
+ retry "gx/ipfs/QmY6UVhgS2ZxhbM5qU23Fnz3daJwfyAuNErd3StmVofnAU/retry-datastore"
27
context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context"
28
)
29
@@ -127,14 +131,30 @@ func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) {
131
return n, nil
132
}
133
134
+func isTooManyFDError(err error) bool {
135
+ perr, ok := err.(*os.PathError)
136
+ if ok && perr.Err == syscall.EMFILE {
137
+ return true
138
+ }
139
+
140
+ return false
141
+}
142
+
143
func setupNode(ctx context.Context, n *IpfsNode, cfg *BuildCfg) error {
144
// setup local peer ID (private key is loaded in online setup)
145
if err := n.loadID(); err != nil {
146
return err
147
}
148
149
+ rds := &retry.Datastore{
150
+ Batching: n.Repo.Datastore(),
151
+ Delay: time.Millisecond * 200,
152
+ Retries: 6,
153
+ TempErrFunc: isTooManyFDError,
154
+ }
155
+
156
var err error
137
- bs := bstore.NewBlockstore(n.Repo.Datastore())
157
+ bs := bstore.NewBlockstore(rds)
158
opts := bstore.DefaultCacheOpts()
159
conf, err := n.Repo.Config()
160
if err != nil {
exchange/bitswap/bitswap.go
+1
-13
@@ -265,7 +265,7 @@ func (bs *Bitswap) HasBlock(blk blocks.Block) error {
265
default:
266
}
267
268
- err := bs.tryPutBlock(blk, 4) // attempt to store block up to four times
268
+ err := bs.blockstore.Put(blk)
269
if err != nil {
270
log.Errorf("Error writing block to datastore: %s", err)
271
return err
@@ -284,18 +284,6 @@ func (bs *Bitswap) HasBlock(blk blocks.Block) error {
284
return nil
285
}
286
287
-func (bs *Bitswap) tryPutBlock(blk blocks.Block, attempts int) error {
288
- var err error
289
- for i := 0; i < attempts; i++ {
290
- if err = bs.blockstore.Put(blk); err == nil {
291
- break
292
- }
293
-
294
- time.Sleep(time.Millisecond * time.Duration(400*(i+1)))
295
- }
296
- return err
297
-}
298
-
287
func (bs *Bitswap) ReceiveMessage(ctx context.Context, p peer.ID, incoming bsmsg.BitSwapMessage) {
288
// This call records changes to wantlists, blocks received,
289
// and number of bytes transfered.
exchange/bitswap/bitswap_test.go
+5
-1
@@ -24,8 +24,12 @@ import (
24
// well under varying conditions
25
const kNetworkDelay = 0 * time.Millisecond
26
27
+func getVirtualNetwork() tn.Network {
28
+ return tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay))
29
+}
30
+
31
func TestClose(t *testing.T) {
28
- vnet := tn.VirtualNetwork(mockrouting.NewServer(), delay.Fixed(kNetworkDelay))
32
+ vnet := getVirtualNetwork()
33
sesgen := NewTestSessionGenerator(vnet)
34
defer sesgen.Close()
35
bgen := blocksutil.NewBlockGenerator()
package.json
+12
@@ -195,6 +195,18 @@
195
"hash": "QmaeHSCBd9XjXxmgHEiKkHtLcMCb2eZsPLKT7bHgBfBkqw",
196
"name": "go-is-domain",
197
"version": "1.0.0"
198
+ },
199
+ {
200
+ "author": "whyrusleeping",
201
+ "hash": "QmY6UVhgS2ZxhbM5qU23Fnz3daJwfyAuNErd3StmVofnAU",
202
+ "name": "retry-datastore",
203
+ "version": "1.1.0"
204
+ },
205
+ {
206
+ "author": "whyrusleeping",
207
+ "hash": "QmdjfJJFxgqqR9skVZDmgiGrbKomSqxpaw12rjLNim5NYR",
208
+ "name": "failstore",
209
+ "version": "1.0.0"
210
}
211
],
212
"gxVersion": "0.4.0",