From 1173c003f5b4ce1e991e78d360635a135091c8e3 Mon Sep 17 00:00:00 2001 From: Kevin Atkinson <k@kevina.org> Date: Thu, 6 Oct 2016 14:54:25 -0400 Subject: [PATCH] Create a "write through" BlockService. Create a block service where all writes are guaranteed to go though to the blockstore. License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org> --- blockservice/blockservice.go | 61 +++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/blockservice/blockservice.go b/blockservice/blockservice.go index d2f068acc..8ecec71f9 100644 --- a/blockservice/blockservice.go +++ b/blockservice/blockservice.go @@ -37,6 +37,9 @@ type BlockService interface { type blockService struct { blockstore blockstore.Blockstore exchange exchange.Interface + // If checkFirst is true then first check that a block doesn't + // already exist to avoid republishing the block on the exchange. + checkFirst bool } // NewBlockService creates a BlockService with given datastore instance. @@ -48,6 +51,21 @@ func New(bs blockstore.Blockstore, rem exchange.Interface) BlockService { return &blockService{ blockstore: bs, exchange: rem, + checkFirst: true, + } +} + +// NewWriteThrough ceates a BlockService that guarantees writes will go +// through to the blockstore and are not skipped by cache checks. +func NewWriteThrough(bs blockstore.Blockstore, rem exchange.Interface) BlockService { + if rem == nil { + log.Warning("blockservice running in local (offline) mode.") + } + + return &blockService{ + blockstore: bs, + exchange: rem, + checkFirst: false, } } @@ -62,22 +80,19 @@ func (bs *blockService) Exchange() exchange.Interface { // 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 *blockService) 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.blockstore.Has(c) - if err != nil { - return nil, err - } + if s.checkFirst { + has, err := s.blockstore.Has(c) + if err != nil { + return nil, err + } - if has { - return c, nil + if has { + return c, nil + } } - err = s.blockstore.Put(o) + err := s.blockstore.Put(o) if err != nil { return nil, err } @@ -91,17 +106,19 @@ func (s *blockService) AddBlock(o blocks.Block) (*cid.Cid, error) { func (s *blockService) AddBlocks(bs []blocks.Block) ([]*cid.Cid, error) { var toput []blocks.Block - for _, b := range bs { - has, err := s.blockstore.Has(b.Cid()) - if err != nil { - return nil, err - } - - if has { - continue + if s.checkFirst { + for _, b := range bs { + has, err := s.blockstore.Has(b.Cid()) + if err != nil { + return nil, err + } + if has { + continue + } + toput = append(toput, b) } - - toput = append(toput, b) + } else { + toput = bs; } err := s.blockstore.PutMany(toput) -- GitLab