github.com/ethersphere/bee/v2@v2.2.0/pkg/storer/debug.go (about)

     1  // Copyright 2023 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package storer
     6  
     7  import (
     8  	"context"
     9  
    10  	storage "github.com/ethersphere/bee/v2/pkg/storage"
    11  	"github.com/ethersphere/bee/v2/pkg/storer/internal/chunkstore"
    12  	pinstore "github.com/ethersphere/bee/v2/pkg/storer/internal/pinning"
    13  	"github.com/ethersphere/bee/v2/pkg/storer/internal/reserve"
    14  	"github.com/ethersphere/bee/v2/pkg/storer/internal/upload"
    15  	"github.com/ethersphere/bee/v2/pkg/swarm"
    16  	"golang.org/x/sync/errgroup"
    17  )
    18  
    19  type UploadStat struct {
    20  	TotalUploaded uint64
    21  	TotalSynced   uint64
    22  	PendingUpload uint64
    23  }
    24  
    25  type PinningStat struct {
    26  	TotalCollections int
    27  	TotalChunks      int
    28  }
    29  
    30  type CacheStat struct {
    31  	Size     int
    32  	Capacity int
    33  }
    34  
    35  type ReserveStat struct {
    36  	SizeWithinRadius int
    37  	TotalSize        int
    38  	Capacity         int
    39  	LastBinIDs       []uint64
    40  	Epoch            uint64
    41  }
    42  
    43  type ChunkStoreStat struct {
    44  	TotalChunks    int
    45  	SharedSlots    int
    46  	ReferenceCount int
    47  }
    48  
    49  type Info struct {
    50  	Upload     UploadStat
    51  	Pinning    PinningStat
    52  	Cache      CacheStat
    53  	Reserve    ReserveStat
    54  	ChunkStore ChunkStoreStat
    55  }
    56  
    57  func (db *DB) DebugInfo(ctx context.Context) (Info, error) {
    58  	eg, ctx := errgroup.WithContext(ctx)
    59  
    60  	var (
    61  		totalChunks  int
    62  		sharedSlots  int
    63  		referenceCnt int
    64  	)
    65  	eg.Go(func() error {
    66  		return chunkstore.IterateChunkEntries(
    67  			db.storage.IndexStore(),
    68  			func(_ swarm.Address, cnt uint32) (bool, error) {
    69  				select {
    70  				case <-ctx.Done():
    71  					return true, ctx.Err()
    72  				case <-db.quit:
    73  					return true, ErrDBQuit
    74  				default:
    75  				}
    76  
    77  				totalChunks++
    78  				referenceCnt += int(cnt)
    79  				if cnt > 1 {
    80  					sharedSlots++
    81  				}
    82  				return false, nil
    83  			},
    84  		)
    85  	})
    86  
    87  	var (
    88  		uploaded      uint64
    89  		synced        uint64
    90  		pendingUpload uint64
    91  	)
    92  	eg.Go(func() error {
    93  		return upload.IterateAllTagItems(db.storage.IndexStore(), func(ti *upload.TagItem) (bool, error) {
    94  			select {
    95  			case <-ctx.Done():
    96  				return true, ctx.Err()
    97  			case <-db.quit:
    98  				return true, ErrDBQuit
    99  			default:
   100  			}
   101  			uploaded += ti.Split
   102  			synced += ti.Synced
   103  			return false, nil
   104  		})
   105  	})
   106  	eg.Go(func() error {
   107  		return upload.IterateAll(db.storage.IndexStore(), func(storage.Item) (bool, error) {
   108  			select {
   109  			case <-ctx.Done():
   110  				return true, ctx.Err()
   111  			case <-db.quit:
   112  				return true, ErrDBQuit
   113  			default:
   114  			}
   115  			pendingUpload++
   116  			return false, nil
   117  		})
   118  	})
   119  
   120  	var (
   121  		collections int
   122  		chunkCount  int
   123  	)
   124  	eg.Go(func() error {
   125  		return pinstore.IterateCollectionStats(
   126  			db.storage.IndexStore(),
   127  			func(stat pinstore.CollectionStat) (bool, error) {
   128  				select {
   129  				case <-ctx.Done():
   130  					return true, ctx.Err()
   131  				case <-db.quit:
   132  					return true, ErrDBQuit
   133  				default:
   134  				}
   135  
   136  				collections++
   137  				chunkCount += int(stat.Total - stat.DupInCollection)
   138  				return false, nil
   139  			},
   140  		)
   141  	})
   142  
   143  	var (
   144  		reserveCapacity         int
   145  		reserveSize             int
   146  		reserveSizeWithinRadius int
   147  
   148  		lastBinIDs []uint64
   149  		epoch      uint64
   150  	)
   151  	if db.reserve != nil {
   152  		reserveCapacity = db.reserve.Capacity()
   153  		reserveSize = db.reserve.Size()
   154  		eg.Go(func() error {
   155  			return db.reserve.IterateChunksItems(db.reserve.Radius(), func(ci *reserve.ChunkBinItem) (bool, error) {
   156  				reserveSizeWithinRadius++
   157  				return false, nil
   158  			})
   159  		})
   160  
   161  		var err error
   162  		lastBinIDs, epoch, err = db.ReserveLastBinIDs()
   163  		if err != nil {
   164  			return Info{}, err
   165  		}
   166  	}
   167  
   168  	if err := eg.Wait(); err != nil {
   169  		return Info{}, err
   170  	}
   171  
   172  	cacheSize := db.cacheObj.Size()
   173  	cacheCapacity := db.cacheObj.Capacity()
   174  
   175  	return Info{
   176  		Upload: UploadStat{
   177  			TotalUploaded: uploaded,
   178  			TotalSynced:   synced,
   179  			PendingUpload: pendingUpload,
   180  		},
   181  		Pinning: PinningStat{
   182  			TotalCollections: collections,
   183  			TotalChunks:      chunkCount,
   184  		},
   185  		Cache: CacheStat{
   186  			Size:     int(cacheSize),
   187  			Capacity: int(cacheCapacity),
   188  		},
   189  		Reserve: ReserveStat{
   190  			SizeWithinRadius: reserveSizeWithinRadius,
   191  			TotalSize:        reserveSize,
   192  			Capacity:         reserveCapacity,
   193  			LastBinIDs:       lastBinIDs,
   194  			Epoch:            epoch,
   195  		},
   196  		ChunkStore: ChunkStoreStat{
   197  			TotalChunks:    totalChunks,
   198  			SharedSlots:    sharedSlots,
   199  			ReferenceCount: referenceCnt,
   200  		},
   201  	}, nil
   202  }