1// Copyright 2016 Keybase Inc. All rights reserved. 2// Use of this source code is governed by a BSD 3// license that can be found in the LICENSE file. 4 5package libkbfs 6 7import ( 8 "github.com/keybase/client/go/kbfs/kbfsblock" 9 "github.com/keybase/client/go/kbfs/kbfscrypto" 10 "github.com/keybase/client/go/kbfs/tlf" 11 "github.com/keybase/client/go/protocol/keybase1" 12 metrics "github.com/rcrowley/go-metrics" 13 "golang.org/x/net/context" 14) 15 16// BlockServerMeasured delegates to another BlockServer instance but 17// also keeps track of stats. 18type BlockServerMeasured struct { 19 delegate BlockServer 20 getTimer metrics.Timer 21 getEncodedSizeTimer metrics.Timer 22 putTimer metrics.Timer 23 putAgainTimer metrics.Timer 24 addBlockReferenceTimer metrics.Timer 25 removeBlockReferencesTimer metrics.Timer 26 archiveBlockReferencesTimer metrics.Timer 27 getLiveBlockReferencesTimer metrics.Timer 28 isUnflushedTimer metrics.Timer 29} 30 31var _ BlockServer = BlockServerMeasured{} 32 33// NewBlockServerMeasured creates and returns a new 34// BlockServerMeasured instance with the given delegate and registry. 35func NewBlockServerMeasured(delegate BlockServer, r metrics.Registry) BlockServerMeasured { 36 getTimer := metrics.GetOrRegisterTimer("BlockServer.Get", r) 37 getEncodedSizeTimer := metrics.GetOrRegisterTimer( 38 "BlockServer.GetEncodedSize", r) 39 putTimer := metrics.GetOrRegisterTimer("BlockServer.Put", r) 40 addBlockReferenceTimer := metrics.GetOrRegisterTimer("BlockServer.AddBlockReference", r) 41 removeBlockReferencesTimer := metrics.GetOrRegisterTimer("BlockServer.RemoveBlockReferences", r) 42 archiveBlockReferencesTimer := metrics.GetOrRegisterTimer("BlockServer.ArchiveBlockReferences", r) 43 getLiveBlockReferencesTimer := metrics.GetOrRegisterTimer("BlockServer.GetLiveBlockReferences", r) 44 isUnflushedTimer := metrics.GetOrRegisterTimer("BlockServer.IsUnflushed", r) 45 return BlockServerMeasured{ 46 delegate: delegate, 47 getTimer: getTimer, 48 getEncodedSizeTimer: getEncodedSizeTimer, 49 putTimer: putTimer, 50 addBlockReferenceTimer: addBlockReferenceTimer, 51 removeBlockReferencesTimer: removeBlockReferencesTimer, 52 archiveBlockReferencesTimer: archiveBlockReferencesTimer, 53 getLiveBlockReferencesTimer: getLiveBlockReferencesTimer, 54 isUnflushedTimer: isUnflushedTimer, 55 } 56} 57 58// FastForwardBackoff implements the BlockServer interface. 59func (b BlockServerMeasured) FastForwardBackoff() { 60 b.delegate.FastForwardBackoff() 61} 62 63// Get implements the BlockServer interface for BlockServerMeasured. 64func (b BlockServerMeasured) Get( 65 ctx context.Context, tlfID tlf.ID, id kbfsblock.ID, 66 context kbfsblock.Context, cacheType DiskBlockCacheType) ( 67 buf []byte, serverHalf kbfscrypto.BlockCryptKeyServerHalf, err error) { 68 b.getTimer.Time(func() { 69 buf, serverHalf, err = b.delegate.Get( 70 ctx, tlfID, id, context, cacheType) 71 }) 72 return buf, serverHalf, err 73} 74 75// GetEncodedSizes implements the BlockServer interface for BlockServerMeasured. 76func (b BlockServerMeasured) GetEncodedSizes( 77 ctx context.Context, tlfID tlf.ID, ids []kbfsblock.ID, 78 contexts []kbfsblock.Context) ( 79 sizes []uint32, statuses []keybase1.BlockStatus, err error) { 80 b.getEncodedSizeTimer.Time(func() { 81 sizes, statuses, err = b.delegate.GetEncodedSizes( 82 ctx, tlfID, ids, contexts) 83 }) 84 return sizes, statuses, err 85} 86 87// Put implements the BlockServer interface for BlockServerMeasured. 88func (b BlockServerMeasured) Put( 89 ctx context.Context, tlfID tlf.ID, id kbfsblock.ID, 90 context kbfsblock.Context, buf []byte, 91 serverHalf kbfscrypto.BlockCryptKeyServerHalf, 92 cacheType DiskBlockCacheType) (err error) { 93 b.putTimer.Time(func() { 94 err = b.delegate.Put( 95 ctx, tlfID, id, context, buf, serverHalf, cacheType) 96 }) 97 return err 98} 99 100// PutAgain implements the BlockServer interface for BlockServerMeasured. 101func (b BlockServerMeasured) PutAgain( 102 ctx context.Context, tlfID tlf.ID, id kbfsblock.ID, 103 context kbfsblock.Context, buf []byte, 104 serverHalf kbfscrypto.BlockCryptKeyServerHalf, 105 cacheType DiskBlockCacheType) (err error) { 106 b.putAgainTimer.Time(func() { 107 err = b.delegate.PutAgain( 108 ctx, tlfID, id, context, buf, serverHalf, cacheType) 109 }) 110 return err 111} 112 113// AddBlockReference implements the BlockServer interface for 114// BlockServerMeasured. 115func (b BlockServerMeasured) AddBlockReference(ctx context.Context, tlfID tlf.ID, 116 id kbfsblock.ID, context kbfsblock.Context) (err error) { 117 b.addBlockReferenceTimer.Time(func() { 118 err = b.delegate.AddBlockReference(ctx, tlfID, id, context) 119 }) 120 return err 121} 122 123// RemoveBlockReferences implements the BlockServer interface for 124// BlockServerMeasured. 125func (b BlockServerMeasured) RemoveBlockReferences(ctx context.Context, 126 tlfID tlf.ID, contexts kbfsblock.ContextMap) ( 127 liveCounts map[kbfsblock.ID]int, err error) { 128 b.removeBlockReferencesTimer.Time(func() { 129 liveCounts, err = b.delegate.RemoveBlockReferences( 130 ctx, tlfID, contexts) 131 }) 132 return liveCounts, err 133} 134 135// ArchiveBlockReferences implements the BlockServer interface for 136// BlockServerMeasured. 137func (b BlockServerMeasured) ArchiveBlockReferences(ctx context.Context, 138 tlfID tlf.ID, contexts kbfsblock.ContextMap) (err error) { 139 b.archiveBlockReferencesTimer.Time(func() { 140 err = b.delegate.ArchiveBlockReferences(ctx, tlfID, contexts) 141 }) 142 return err 143} 144 145// GetLiveBlockReferences implements the BlockServer interface for 146// BlockServerMeasured. 147func (b BlockServerMeasured) GetLiveBlockReferences( 148 ctx context.Context, tlfID tlf.ID, contexts kbfsblock.ContextMap) ( 149 liveCounts map[kbfsblock.ID]int, err error) { 150 b.getLiveBlockReferencesTimer.Time(func() { 151 liveCounts, err = b.delegate.GetLiveBlockReferences( 152 ctx, tlfID, contexts) 153 }) 154 return liveCounts, err 155} 156 157// IsUnflushed implements the BlockServer interface for BlockServerMeasured. 158func (b BlockServerMeasured) IsUnflushed(ctx context.Context, tlfID tlf.ID, 159 id kbfsblock.ID) (isUnflushed bool, err error) { 160 b.isUnflushedTimer.Time(func() { 161 isUnflushed, err = b.delegate.IsUnflushed(ctx, tlfID, id) 162 }) 163 return isUnflushed, err 164 165} 166 167// Shutdown implements the BlockServer interface for 168// BlockServerMeasured. 169func (b BlockServerMeasured) Shutdown(ctx context.Context) { 170 b.delegate.Shutdown(ctx) 171} 172 173// RefreshAuthToken implements the BlockServer interface for 174// BlockServerMeasured. 175func (b BlockServerMeasured) RefreshAuthToken(ctx context.Context) { 176 b.delegate.RefreshAuthToken(ctx) 177} 178 179// GetUserQuotaInfo implements the BlockServer interface for BlockServerMeasured 180func (b BlockServerMeasured) GetUserQuotaInfo(ctx context.Context) (info *kbfsblock.QuotaInfo, err error) { 181 return b.delegate.GetUserQuotaInfo(ctx) 182} 183 184// GetTeamQuotaInfo implements the BlockServer interface for BlockServerMeasured 185func (b BlockServerMeasured) GetTeamQuotaInfo( 186 ctx context.Context, tid keybase1.TeamID) ( 187 info *kbfsblock.QuotaInfo, err error) { 188 return b.delegate.GetTeamQuotaInfo(ctx, tid) 189} 190