github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/goid/routing.go (about)

     1  package goid
     2  
     3  // LocalStorage provides goroutine-local variables.
     4  type LocalStorage interface {
     5  
     6  	// Get returns the value in the current goroutine's local storage, if it was set before.
     7  	Get() (value any)
     8  
     9  	// Set copy the value into the current goroutine's local storage, and return the old value.
    10  	Set(value any) (oldValue any)
    11  
    12  	// Del delete the value from the current goroutine's local storage, and return it.
    13  	Del() (oldValue any)
    14  
    15  	// Clear delete values from all goroutine's local storages.
    16  	Clear()
    17  }
    18  
    19  // ImmutableContext represents all local storages of one goroutine.
    20  type ImmutableContext struct {
    21  	gid    int64
    22  	values map[uintptr]any
    23  }
    24  
    25  // Go start an new goroutine, and copy all local storages from current goroutine.
    26  func Go(f func()) {
    27  	ic := BackupContext()
    28  	go func() {
    29  		InheritContext(ic)
    30  		f()
    31  	}()
    32  }
    33  
    34  // BackupContext copy all local storages into an ImmutableContext instance.
    35  func BackupContext() *ImmutableContext {
    36  	s := loadCurrentStore()
    37  	data := make(map[uintptr]any, len(s.values))
    38  	for k, v := range s.values {
    39  		data[k] = v
    40  	}
    41  	return &ImmutableContext{gid: s.gid, values: data}
    42  }
    43  
    44  // InheritContext load the specified ImmutableContext instance into the local storage of current goroutine.
    45  func InheritContext(ic *ImmutableContext) {
    46  	if ic == nil || ic.values == nil {
    47  		return
    48  	}
    49  	s := loadCurrentStore()
    50  	for k, v := range ic.values {
    51  		s.values[k] = v
    52  	}
    53  }
    54  
    55  // NewLocalStorage create and return an new LocalStorage instance.
    56  func NewLocalStorage() LocalStorage {
    57  	t := new(storage)
    58  	t.Clear()
    59  	return t
    60  }
    61  
    62  // Goid return the current goroutine's unique id.
    63  // It will try get gid by native cgo/asm for better performance,
    64  // and could parse gid from stack for failover supporting.
    65  func Goid() (id int64) {
    66  	return getGoidByStack()
    67  }
    68  
    69  // AllGoids return all goroutine's goid in the current golang process.
    70  // It will try load all goid from runtime natively for better performance,
    71  // and fallover to runtime.Stack, which is realy inefficient.
    72  func AllGoids() (ids []int64) {
    73  	return getAllGoidByStack()
    74  }