github.com/ledgerwatch/erigon-lib@v1.0.0/common/dbg/experiments.go (about)

     1  /*
     2     Copyright 2021 Erigon contributors
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package dbg
    18  
    19  import (
    20  	"os"
    21  	"runtime"
    22  	"strconv"
    23  	"sync"
    24  	"time"
    25  
    26  	"github.com/ledgerwatch/log/v3"
    27  )
    28  
    29  var doMemstat = true
    30  
    31  func init() {
    32  	_, ok := os.LookupEnv("NO_MEMSTAT")
    33  	if ok {
    34  		doMemstat = false
    35  	}
    36  }
    37  
    38  func DoMemStat() bool { return doMemstat }
    39  func ReadMemStats(m *runtime.MemStats) {
    40  	if doMemstat {
    41  		runtime.ReadMemStats(m)
    42  	}
    43  }
    44  
    45  var (
    46  	writeMap     bool
    47  	writeMapOnce sync.Once
    48  )
    49  
    50  func WriteMap() bool {
    51  	writeMapOnce.Do(func() {
    52  		v, _ := os.LookupEnv("WRITE_MAP")
    53  		if v == "true" {
    54  			writeMap = true
    55  			log.Info("[Experiment]", "WRITE_MAP", writeMap)
    56  		}
    57  	})
    58  	return writeMap
    59  }
    60  
    61  var (
    62  	dirtySace     uint64
    63  	dirtySaceOnce sync.Once
    64  )
    65  
    66  func DirtySpace() uint64 {
    67  	dirtySaceOnce.Do(func() {
    68  		v, _ := os.LookupEnv("MDBX_DIRTY_SPACE_MB")
    69  		if v != "" {
    70  			i, err := strconv.Atoi(v)
    71  			if err != nil {
    72  				panic(err)
    73  			}
    74  			dirtySace = uint64(i * 1024 * 1024)
    75  			log.Info("[Experiment]", "MDBX_DIRTY_SPACE_MB", dirtySace)
    76  		}
    77  	})
    78  	return dirtySace
    79  }
    80  
    81  var (
    82  	noSync     bool
    83  	noSyncOnce sync.Once
    84  )
    85  
    86  func NoSync() bool {
    87  	noSyncOnce.Do(func() {
    88  		v, _ := os.LookupEnv("NO_SYNC")
    89  		if v == "true" {
    90  			noSync = true
    91  			log.Info("[Experiment]", "NO_SYNC", noSync)
    92  		}
    93  	})
    94  	return noSync
    95  }
    96  
    97  var (
    98  	mergeTr     int
    99  	mergeTrOnce sync.Once
   100  )
   101  
   102  func MergeTr() int {
   103  	mergeTrOnce.Do(func() {
   104  		v, _ := os.LookupEnv("MERGE_THRESHOLD")
   105  		if v != "" {
   106  			i, err := strconv.Atoi(v)
   107  			if err != nil {
   108  				panic(err)
   109  			}
   110  			if i < 0 || i > 4 {
   111  				panic(i)
   112  			}
   113  			mergeTr = i
   114  			log.Info("[Experiment]", "MERGE_THRESHOLD", mergeTr)
   115  		}
   116  	})
   117  	return mergeTr
   118  }
   119  
   120  var (
   121  	mdbxReadahead     bool
   122  	mdbxReadaheadOnce sync.Once
   123  )
   124  
   125  func MdbxReadAhead() bool {
   126  	mdbxReadaheadOnce.Do(func() {
   127  		v, _ := os.LookupEnv("MDBX_READAHEAD")
   128  		if v == "true" {
   129  			mdbxReadahead = true
   130  			log.Info("[Experiment]", "MDBX_READAHEAD", mdbxReadahead)
   131  		}
   132  	})
   133  	return mdbxReadahead
   134  }
   135  
   136  var (
   137  	discardHistory     bool
   138  	discardHistoryOnce sync.Once
   139  )
   140  
   141  func DiscardHistory() bool {
   142  	discardHistoryOnce.Do(func() {
   143  		v, _ := os.LookupEnv("DISCARD_HISTORY")
   144  		if v == "true" {
   145  			discardHistory = true
   146  			log.Info("[Experiment]", "DISCARD_HISTORY", discardHistory)
   147  		}
   148  	})
   149  	return discardHistory
   150  }
   151  
   152  var (
   153  	bigRoTx    uint
   154  	getBigRoTx sync.Once
   155  )
   156  
   157  // DEBUG_BIG_RO_TX_KB - print logs with info about large read-only transactions
   158  // DEBUG_BIG_RW_TX_KB - print logs with info about large read-write transactions
   159  // DEBUG_SLOW_COMMIT_MS - print logs with commit timing details if commit is slower than this threshold
   160  func BigRoTxKb() uint {
   161  	getBigRoTx.Do(func() {
   162  		v, _ := os.LookupEnv("DEBUG_BIG_RO_TX_KB")
   163  		if v != "" {
   164  			i, err := strconv.Atoi(v)
   165  			if err != nil {
   166  				panic(err)
   167  			}
   168  			bigRoTx = uint(i)
   169  			log.Info("[Experiment]", "DEBUG_BIG_RO_TX_KB", bigRoTx)
   170  		}
   171  	})
   172  	return bigRoTx
   173  }
   174  
   175  var (
   176  	bigRwTx    uint
   177  	getBigRwTx sync.Once
   178  )
   179  
   180  func BigRwTxKb() uint {
   181  	getBigRwTx.Do(func() {
   182  		v, _ := os.LookupEnv("DEBUG_BIG_RW_TX_KB")
   183  		if v != "" {
   184  			i, err := strconv.Atoi(v)
   185  			if err != nil {
   186  				panic(err)
   187  			}
   188  			bigRwTx = uint(i)
   189  			log.Info("[Experiment]", "DEBUG_BIG_RW_TX_KB", bigRwTx)
   190  		}
   191  	})
   192  	return bigRwTx
   193  }
   194  
   195  var (
   196  	slowCommit     time.Duration
   197  	slowCommitOnce sync.Once
   198  )
   199  
   200  func SlowCommit() time.Duration {
   201  	slowCommitOnce.Do(func() {
   202  		v, _ := os.LookupEnv("SLOW_COMMIT")
   203  		if v != "" {
   204  			var err error
   205  			slowCommit, err = time.ParseDuration(v)
   206  			if err != nil {
   207  				panic(err)
   208  			}
   209  			log.Info("[Experiment]", "SLOW_COMMIT", slowCommit.String())
   210  		}
   211  	})
   212  	return slowCommit
   213  }
   214  
   215  var (
   216  	slowTx     time.Duration
   217  	slowTxOnce sync.Once
   218  )
   219  
   220  func SlowTx() time.Duration {
   221  	slowTxOnce.Do(func() {
   222  		v, _ := os.LookupEnv("SLOW_TX")
   223  		if v != "" {
   224  			var err error
   225  			slowTx, err = time.ParseDuration(v)
   226  			if err != nil {
   227  				panic(err)
   228  			}
   229  			log.Info("[Experiment]", "SLOW_TX", slowTx.String())
   230  		}
   231  	})
   232  	return slowTx
   233  }
   234  
   235  var (
   236  	stopBeforeStage     string
   237  	stopBeforeStageFlag sync.Once
   238  	stopAfterStage      string
   239  	stopAfterStageFlag  sync.Once
   240  )
   241  
   242  func StopBeforeStage() string {
   243  	f := func() {
   244  		v, _ := os.LookupEnv("STOP_BEFORE_STAGE") // see names in eth/stagedsync/stages/stages.go
   245  		if v != "" {
   246  			stopBeforeStage = v
   247  			log.Info("[Experiment]", "STOP_BEFORE_STAGE", stopBeforeStage)
   248  		}
   249  	}
   250  	stopBeforeStageFlag.Do(f)
   251  	return stopBeforeStage
   252  }
   253  
   254  // TODO(allada) We should possibly consider removing `STOP_BEFORE_STAGE`, as `STOP_AFTER_STAGE` can
   255  // perform all same the functionality, but due to reverse compatibility reasons we are going to
   256  // leave it.
   257  func StopAfterStage() string {
   258  	f := func() {
   259  		v, _ := os.LookupEnv("STOP_AFTER_STAGE") // see names in eth/stagedsync/stages/stages.go
   260  		if v != "" {
   261  			stopAfterStage = v
   262  			log.Info("[Experiment]", "STOP_AFTER_STAGE", stopAfterStage)
   263  		}
   264  	}
   265  	stopAfterStageFlag.Do(f)
   266  	return stopAfterStage
   267  }
   268  
   269  var (
   270  	stopAfterReconst     bool
   271  	stopAfterReconstOnce sync.Once
   272  )
   273  
   274  func StopAfterReconst() bool {
   275  	stopAfterReconstOnce.Do(func() {
   276  		v, _ := os.LookupEnv("STOP_AFTER_RECONSTITUTE")
   277  		if v == "true" {
   278  			stopAfterReconst = true
   279  			log.Info("[Experiment]", "STOP_AFTER_RECONSTITUTE", writeMap)
   280  		}
   281  	})
   282  	return stopAfterReconst
   283  }