@cryptotaxi247 / kubo / commits / 881300804

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",