Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-merkledag
Commits
70e5c88f
Commit
70e5c88f
authored
Feb 10, 2016
by
Jeromy
Committed by
Jeromy
Apr 12, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
don't fail promises that already succeeded
License: MIT Signed-off-by:
Jeromy
<
jeromyj@gmail.com
>
parent
1535a6a9
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
87 additions
and
14 deletions
+87
-14
merkledag.go
merkledag.go
+43
-14
merkledag_test.go
merkledag_test.go
+44
-0
No files found.
merkledag.go
View file @
70e5c88f
...
...
@@ -176,9 +176,8 @@ func GetNodes(ctx context.Context, ds DAGService, keys []key.Key) []NodeGetter {
}
promises
:=
make
([]
NodeGetter
,
len
(
keys
))
sendChans
:=
make
([]
chan
<-
*
Node
,
len
(
keys
))
for
i
:=
range
keys
{
promises
[
i
]
,
sendChans
[
i
]
=
newNodePromise
(
ctx
)
promises
[
i
]
=
newNodePromise
(
ctx
)
}
dedupedKeys
:=
dedupeKeys
(
keys
)
...
...
@@ -199,7 +198,9 @@ func GetNodes(ctx context.Context, ds DAGService, keys []key.Key) []NodeGetter {
}
if
opt
.
Err
!=
nil
{
log
.
Error
(
"error fetching: "
,
opt
.
Err
)
for
_
,
p
:=
range
promises
{
p
.
Fail
(
opt
.
Err
)
}
return
}
...
...
@@ -214,7 +215,7 @@ func GetNodes(ctx context.Context, ds DAGService, keys []key.Key) []NodeGetter {
is
:=
FindLinks
(
keys
,
k
,
0
)
for
_
,
i
:=
range
is
{
count
++
sendChans
[
i
]
<-
nd
promises
[
i
]
.
Send
(
nd
)
}
case
<-
ctx
.
Done
()
:
return
...
...
@@ -237,18 +238,18 @@ func dedupeKeys(ks []key.Key) []key.Key {
return
out
}
func
newNodePromise
(
ctx
context
.
Context
)
(
NodeGetter
,
chan
<-
*
Node
)
{
ch
:=
make
(
chan
*
Node
,
1
)
func
newNodePromise
(
ctx
context
.
Context
)
NodeGetter
{
return
&
nodePromise
{
recv
:
ch
,
recv
:
make
(
chan
*
Node
,
1
)
,
ctx
:
ctx
,
err
:
make
(
chan
error
,
1
),
}
,
ch
}
}
type
nodePromise
struct
{
cache
*
Node
recv
<-
chan
*
Node
clk
sync
.
Mutex
recv
chan
*
Node
ctx
context
.
Context
err
chan
error
}
...
...
@@ -260,20 +261,49 @@ type nodePromise struct {
type
NodeGetter
interface
{
Get
(
context
.
Context
)
(
*
Node
,
error
)
Fail
(
err
error
)
Send
(
*
Node
)
}
func
(
np
*
nodePromise
)
Fail
(
err
error
)
{
np
.
clk
.
Lock
()
v
:=
np
.
cache
np
.
clk
.
Unlock
()
// if promise has a value, don't fail it
if
v
!=
nil
{
return
}
np
.
err
<-
err
}
func
(
np
*
nodePromise
)
Get
(
ctx
context
.
Context
)
(
*
Node
,
error
)
{
func
(
np
*
nodePromise
)
Send
(
nd
*
Node
)
{
var
already
bool
np
.
clk
.
Lock
()
if
np
.
cache
!=
nil
{
return
np
.
cache
,
nil
already
=
true
}
np
.
cache
=
nd
np
.
clk
.
Unlock
()
if
already
{
panic
(
"sending twice to the same promise is an error!"
)
}
np
.
recv
<-
nd
}
func
(
np
*
nodePromise
)
Get
(
ctx
context
.
Context
)
(
*
Node
,
error
)
{
np
.
clk
.
Lock
()
c
:=
np
.
cache
np
.
clk
.
Unlock
()
if
c
!=
nil
{
return
c
,
nil
}
select
{
case
blk
:=
<-
np
.
recv
:
np
.
cache
=
blk
case
nd
:=
<-
np
.
recv
:
return
nd
,
nil
case
<-
np
.
ctx
.
Done
()
:
return
nil
,
np
.
ctx
.
Err
()
case
<-
ctx
.
Done
()
:
...
...
@@ -281,7 +311,6 @@ func (np *nodePromise) Get(ctx context.Context) (*Node, error) {
case
err
:=
<-
np
.
err
:
return
nil
,
err
}
return
np
.
cache
,
nil
}
type
Batch
struct
{
...
...
merkledag_test.go
View file @
70e5c88f
...
...
@@ -20,6 +20,7 @@ import (
imp
"github.com/ipfs/go-ipfs/importer"
chunk
"github.com/ipfs/go-ipfs/importer/chunk"
.
"github.com/ipfs/go-ipfs/merkledag"
dstest
"github.com/ipfs/go-ipfs/merkledag/test"
"github.com/ipfs/go-ipfs/pin"
uio
"github.com/ipfs/go-ipfs/unixfs/io"
u
"gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
...
...
@@ -323,3 +324,46 @@ func TestEnumerateChildren(t *testing.T) {
traverse
(
root
)
}
func
TestFetchFailure
(
t
*
testing
.
T
)
{
ds
:=
dstest
.
Mock
()
ds_bad
:=
dstest
.
Mock
()
top
:=
new
(
Node
)
for
i
:=
0
;
i
<
10
;
i
++
{
nd
:=
&
Node
{
Data
:
[]
byte
{
byte
(
'a'
+
i
)}}
_
,
err
:=
ds
.
Add
(
nd
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
top
.
AddNodeLinkClean
(
fmt
.
Sprintf
(
"AA%d"
,
i
),
nd
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
for
i
:=
0
;
i
<
10
;
i
++
{
nd
:=
&
Node
{
Data
:
[]
byte
{
'f'
,
'a'
+
byte
(
i
)}}
_
,
err
:=
ds_bad
.
Add
(
nd
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
top
.
AddNodeLinkClean
(
fmt
.
Sprintf
(
"BB%d"
,
i
),
nd
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
getters
:=
GetDAG
(
context
.
Background
(),
ds
,
top
)
for
i
,
getter
:=
range
getters
{
_
,
err
:=
getter
.
Get
(
context
.
Background
())
if
err
!=
nil
&&
i
<
10
{
t
.
Fatal
(
err
)
}
if
err
==
nil
&&
i
>=
10
{
t
.
Fatal
(
"should have failed request"
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment