github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/scrape/scrape_manager_utils.go (about) 1 package scrapePkg 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 9 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/colors" 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger" 12 ) 13 14 // Report prints out a report of the progress of the scraper. 15 func (bm *BlazeManager) report(nBlocks, perChunk, nChunks, nAppsNow, nAppsFound, nAddrsFound int) { 16 _ = nBlocks // linter 17 nNeeded := perChunk - base.Min(perChunk, nAppsNow) 18 appsPerAddr := float64(nAppsFound) / float64(nAddrsFound) 19 pctFull := float64(nAppsNow) / float64(perChunk) 20 pctStr := fmt.Sprintf("%0.1f%%", pctFull*100) 21 if len(pctStr) < 5 { 22 pctStr = " " + pctStr 23 } 24 chunksStr := "" 25 if nChunks > 0 { 26 chunksStr = fmt.Sprintf(" created {%d} chunk(s)", nChunks) 27 } else { 28 chunksStr = fmt.Sprintf(" %s", bm.chain) 29 } 30 31 report := `%7.7s @#% 9d}: {% 8d}/{% 8d} ({%0.1f apps/addr}) stage {% 8d} need {% 8d} (@%5.5s})%s` 32 msg := fmt.Sprintf(report, 33 bm.chain, 34 bm.EndBlock()-1, 35 nAppsFound, 36 nAddrsFound, 37 appsPerAddr, 38 nAppsNow, 39 nNeeded, 40 pctStr, 41 chunksStr, 42 ) 43 logger.Info(colors.Colored(msg)) 44 } 45 46 // Pause goes to sleep for a period of time based on the settings. 47 func (opts *ScrapeOptions) pause(ctx context.Context, dist base.Blknum) { 48 // sleepOrCancel is a helper that waits ms milliseconds unless the context has been cancelled. 49 sleepOrCancel := func(ms time.Duration) (ok bool) { 50 // We need to create a new timer explicitly, so we can cleanup the memory. 51 // See the documentation of time.After 52 timer := time.NewTimer(ms) 53 select { 54 case <-ctx.Done(): 55 // If the context has been cancelled, we need to drain the timer's channel 56 // to make sure nothing "leaks" 57 if !timer.Stop() { 58 <-timer.C 59 } 60 return false 61 case <-timer.C: 62 // Since we have just read the channel's value, we can just call Stop 63 timer.Stop() 64 return true 65 } 66 } 67 // we always pause at least a quarter of a second to allow the node to 'rest' 68 if !sleepOrCancel(250 * time.Millisecond) { 69 return 70 } 71 isDefaultSleep := opts.Sleep >= 13 && opts.Sleep <= 14 72 shouldSleep := !isDefaultSleep || dist <= base.Blknum(2*config.GetScrape(opts.Globals.Chain).UnripeDist) 73 if shouldSleep { 74 sleep := opts.Sleep // this value may change elsewhere allow us to break out of sleeping???? 75 logger.Progress(sleep > 1, "Sleeping for", sleep, "seconds -", dist, "away from head.") 76 halfSecs := (sleep * 2) - 1 // we already slept one quarter of a second 77 for i := 0; i < int(halfSecs); i++ { 78 if !sleepOrCancel(500 * time.Millisecond) { 79 return 80 } 81 } 82 } 83 }