github.com/Rookout/GoSDK@v0.1.48/pkg/services/instrumentation/gc_controller.go (about)

     1  package instrumentation
     2  
     3  import (
     4  	"context"
     5  	"runtime/debug"
     6  	"time"
     7  
     8  	"github.com/Rookout/GoSDK/pkg/logger"
     9  )
    10  
    11  type gcController struct {
    12  	gcEnabled         bool
    13  	triggerCounter    int
    14  	enableGCTimer     <-chan time.Time
    15  	originalGCPercent int
    16  }
    17  
    18  func newGCController() *gcController {
    19  	originalGCPercent := debug.SetGCPercent(-1)
    20  	debug.SetGCPercent(originalGCPercent)
    21  
    22  	return &gcController{
    23  		gcEnabled:         true,
    24  		triggerCounter:    0,
    25  		enableGCTimer:     nil,
    26  		originalGCPercent: originalGCPercent,
    27  	}
    28  }
    29  
    30  func (g *gcController) start(ctx context.Context, triggerChan chan bool) {
    31  	for {
    32  		select {
    33  		case <-ctx.Done():
    34  			g.enableGC()
    35  			return
    36  		case triggerStart := <-triggerChan:
    37  			if triggerStart {
    38  				if g.triggerStart() {
    39  					g.disableGC()
    40  				}
    41  			} else {
    42  				if g.triggerEnd() {
    43  					g.startEnableGCTimer()
    44  				}
    45  			}
    46  		
    47  		case <-g.enableGCTimer:
    48  			g.enableGC()
    49  		}
    50  	}
    51  }
    52  
    53  func (g *gcController) triggerStart() bool {
    54  	g.triggerCounter++
    55  	
    56  	return true
    57  }
    58  
    59  func (g *gcController) triggerEnd() bool {
    60  	g.triggerCounter--
    61  
    62  	
    63  	if g.triggerCounter < 0 {
    64  		logger.Logger().Fatalf("Something bad happened. Trigger counter is a negative number: %d\n", g.triggerCounter)
    65  		g.triggerCounter = 0
    66  		return true
    67  	}
    68  
    69  	
    70  	return g.triggerCounter == 0
    71  }
    72  
    73  func (g *gcController) disableGC() {
    74  	prevGCPercent := debug.SetGCPercent(-1)
    75  	if prevGCPercent != -1 && prevGCPercent != g.originalGCPercent {
    76  		logger.Logger().Infof("GC percent was changed from %d to %d", g.originalGCPercent, prevGCPercent)
    77  		g.originalGCPercent = prevGCPercent
    78  	}
    79  	g.enableGCTimer = nil
    80  }
    81  
    82  func (g *gcController) enableGC() {
    83  	debug.SetGCPercent(g.originalGCPercent)
    84  }
    85  
    86  func (g *gcController) startEnableGCTimer() {
    87  	g.enableGCTimer = time.After(1 * time.Millisecond)
    88  }