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-blockservice
Commits
67829690
Commit
67829690
authored
Oct 05, 2016
by
Kevin Atkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make BlockService an interface.
License: MIT Signed-off-by:
Kevin Atkinson
<
k@kevina.org
>
parent
b36159b9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
47 additions
and
29 deletions
+47
-29
blockservice.go
blockservice.go
+45
-27
test/mock.go
test/mock.go
+2
-2
No files found.
blockservice.go
View file @
67829690
...
...
@@ -23,34 +23,52 @@ var ErrNotFound = errors.New("blockservice: key not found")
// BlockService is a hybrid block datastore. It stores data in a local
// datastore and may retrieve data from a remote Exchange.
// It uses an internal `datastore.Datastore` instance to store values.
type
BlockService
struct
{
// TODO don't expose underlying impl details
Blockstore
blockstore
.
Blockstore
Exchange
exchange
.
Interface
type
BlockService
interface
{
Blockstore
()
blockstore
.
Blockstore
Exchange
()
exchange
.
Interface
AddBlock
(
o
blocks
.
Block
)
(
*
cid
.
Cid
,
error
)
AddBlocks
(
bs
[]
blocks
.
Block
)
([]
*
cid
.
Cid
,
error
)
GetBlock
(
ctx
context
.
Context
,
c
*
cid
.
Cid
)
(
blocks
.
Block
,
error
)
GetBlocks
(
ctx
context
.
Context
,
ks
[]
*
cid
.
Cid
)
<-
chan
blocks
.
Block
DeleteBlock
(
o
blocks
.
Block
)
error
Close
()
error
}
type
blockService
struct
{
blockstore
blockstore
.
Blockstore
exchange
exchange
.
Interface
}
// NewBlockService creates a BlockService with given datastore instance.
func
New
(
bs
blockstore
.
Blockstore
,
rem
exchange
.
Interface
)
*
BlockService
{
func
New
(
bs
blockstore
.
Blockstore
,
rem
exchange
.
Interface
)
BlockService
{
if
rem
==
nil
{
log
.
Warning
(
"blockservice running in local (offline) mode."
)
}
return
&
B
lockService
{
B
lockstore
:
bs
,
E
xchange
:
rem
,
return
&
b
lockService
{
b
lockstore
:
bs
,
e
xchange
:
rem
,
}
}
func
(
bs
*
blockService
)
Blockstore
()
blockstore
.
Blockstore
{
return
bs
.
blockstore
}
func
(
bs
*
blockService
)
Exchange
()
exchange
.
Interface
{
return
bs
.
exchange
}
// AddBlock adds a particular block to the service, Putting it into the datastore.
// TODO pass a context into this if the remote.HasBlock is going to remain here.
func
(
s
*
B
lockService
)
AddBlock
(
o
blocks
.
Block
)
(
*
cid
.
Cid
,
error
)
{
func
(
s
*
b
lockService
)
AddBlock
(
o
blocks
.
Block
)
(
*
cid
.
Cid
,
error
)
{
// TODO: while this is a great optimization, we should think about the
// possibility of streaming writes directly to disk. If we can pass this object
// all the way down to the datastore without having to 'buffer' its data,
// we could implement a `WriteTo` method on it that could do a streaming write
// of the content, saving us (probably) considerable memory.
c
:=
o
.
Cid
()
has
,
err
:=
s
.
B
lockstore
.
Has
(
c
)
has
,
err
:=
s
.
b
lockstore
.
Has
(
c
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -59,22 +77,22 @@ func (s *BlockService) AddBlock(o blocks.Block) (*cid.Cid, error) {
return
c
,
nil
}
err
=
s
.
B
lockstore
.
Put
(
o
)
err
=
s
.
b
lockstore
.
Put
(
o
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
s
.
E
xchange
.
HasBlock
(
o
);
err
!=
nil
{
if
err
:=
s
.
e
xchange
.
HasBlock
(
o
);
err
!=
nil
{
return
nil
,
errors
.
New
(
"blockservice is closed"
)
}
return
c
,
nil
}
func
(
s
*
B
lockService
)
AddBlocks
(
bs
[]
blocks
.
Block
)
([]
*
cid
.
Cid
,
error
)
{
func
(
s
*
b
lockService
)
AddBlocks
(
bs
[]
blocks
.
Block
)
([]
*
cid
.
Cid
,
error
)
{
var
toput
[]
blocks
.
Block
for
_
,
b
:=
range
bs
{
has
,
err
:=
s
.
B
lockstore
.
Has
(
b
.
Cid
())
has
,
err
:=
s
.
b
lockstore
.
Has
(
b
.
Cid
())
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -86,14 +104,14 @@ func (s *BlockService) AddBlocks(bs []blocks.Block) ([]*cid.Cid, error) {
toput
=
append
(
toput
,
b
)
}
err
:=
s
.
B
lockstore
.
PutMany
(
toput
)
err
:=
s
.
b
lockstore
.
PutMany
(
toput
)
if
err
!=
nil
{
return
nil
,
err
}
var
ks
[]
*
cid
.
Cid
for
_
,
o
:=
range
toput
{
if
err
:=
s
.
E
xchange
.
HasBlock
(
o
);
err
!=
nil
{
if
err
:=
s
.
e
xchange
.
HasBlock
(
o
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"blockservice is closed (%s)"
,
err
)
}
...
...
@@ -104,19 +122,19 @@ func (s *BlockService) AddBlocks(bs []blocks.Block) ([]*cid.Cid, error) {
// GetBlock retrieves a particular block from the service,
// Getting it from the datastore using the key (hash).
func
(
s
*
B
lockService
)
GetBlock
(
ctx
context
.
Context
,
c
*
cid
.
Cid
)
(
blocks
.
Block
,
error
)
{
func
(
s
*
b
lockService
)
GetBlock
(
ctx
context
.
Context
,
c
*
cid
.
Cid
)
(
blocks
.
Block
,
error
)
{
log
.
Debugf
(
"BlockService GetBlock: '%s'"
,
c
)
block
,
err
:=
s
.
B
lockstore
.
Get
(
c
)
block
,
err
:=
s
.
b
lockstore
.
Get
(
c
)
if
err
==
nil
{
return
block
,
nil
}
if
err
==
blockstore
.
ErrNotFound
&&
s
.
E
xchange
!=
nil
{
if
err
==
blockstore
.
ErrNotFound
&&
s
.
e
xchange
!=
nil
{
// TODO be careful checking ErrNotFound. If the underlying
// implementation changes, this will break.
log
.
Debug
(
"Blockservice: Searching bitswap"
)
blk
,
err
:=
s
.
E
xchange
.
GetBlock
(
ctx
,
c
)
blk
,
err
:=
s
.
e
xchange
.
GetBlock
(
ctx
,
c
)
if
err
!=
nil
{
if
err
==
blockstore
.
ErrNotFound
{
return
nil
,
ErrNotFound
...
...
@@ -137,13 +155,13 @@ func (s *BlockService) GetBlock(ctx context.Context, c *cid.Cid) (blocks.Block,
// GetBlocks gets a list of blocks asynchronously and returns through
// the returned channel.
// NB: No guarantees are made about order.
func
(
s
*
B
lockService
)
GetBlocks
(
ctx
context
.
Context
,
ks
[]
*
cid
.
Cid
)
<-
chan
blocks
.
Block
{
func
(
s
*
b
lockService
)
GetBlocks
(
ctx
context
.
Context
,
ks
[]
*
cid
.
Cid
)
<-
chan
blocks
.
Block
{
out
:=
make
(
chan
blocks
.
Block
,
0
)
go
func
()
{
defer
close
(
out
)
var
misses
[]
*
cid
.
Cid
for
_
,
c
:=
range
ks
{
hit
,
err
:=
s
.
B
lockstore
.
Get
(
c
)
hit
,
err
:=
s
.
b
lockstore
.
Get
(
c
)
if
err
!=
nil
{
misses
=
append
(
misses
,
c
)
continue
...
...
@@ -160,7 +178,7 @@ func (s *BlockService) GetBlocks(ctx context.Context, ks []*cid.Cid) <-chan bloc
return
}
rblocks
,
err
:=
s
.
E
xchange
.
GetBlocks
(
ctx
,
misses
)
rblocks
,
err
:=
s
.
e
xchange
.
GetBlocks
(
ctx
,
misses
)
if
err
!=
nil
{
log
.
Debugf
(
"Error with GetBlocks: %s"
,
err
)
return
...
...
@@ -178,11 +196,11 @@ func (s *BlockService) GetBlocks(ctx context.Context, ks []*cid.Cid) <-chan bloc
}
// DeleteBlock deletes a block in the blockservice from the datastore
func
(
s
*
B
lockService
)
DeleteBlock
(
o
blocks
.
Block
)
error
{
return
s
.
B
lockstore
.
DeleteBlock
(
o
.
Cid
())
func
(
s
*
b
lockService
)
DeleteBlock
(
o
blocks
.
Block
)
error
{
return
s
.
b
lockstore
.
DeleteBlock
(
o
.
Cid
())
}
func
(
s
*
B
lockService
)
Close
()
error
{
func
(
s
*
b
lockService
)
Close
()
error
{
log
.
Debug
(
"blockservice is shutting down..."
)
return
s
.
E
xchange
.
Close
()
return
s
.
e
xchange
.
Close
()
}
test/mock.go
View file @
67829690
...
...
@@ -9,13 +9,13 @@ import (
)
// Mocks returns |n| connected mock Blockservices
func
Mocks
(
n
int
)
[]
*
BlockService
{
func
Mocks
(
n
int
)
[]
BlockService
{
net
:=
tn
.
VirtualNetwork
(
mockrouting
.
NewServer
(),
delay
.
Fixed
(
0
))
sg
:=
bitswap
.
NewTestSessionGenerator
(
net
)
instances
:=
sg
.
Instances
(
n
)
var
servs
[]
*
BlockService
var
servs
[]
BlockService
for
_
,
i
:=
range
instances
{
servs
=
append
(
servs
,
New
(
i
.
Blockstore
(),
i
.
Exchange
))
}
...
...
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