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 }