github.com/cloudwego/localsession@v0.0.2/example_test.go (about) 1 // Copyright 2023 CloudWeGo Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package localsession 16 17 import ( 18 "context" 19 "runtime/pprof" 20 "sync" 21 "time" 22 ) 23 24 func ASSERT(v bool) { 25 if !v { 26 panic("not true!") 27 } 28 } 29 30 func GetCurSession() Session { 31 s, ok := CurSession() 32 if !ok { 33 panic("can't get current session!") 34 } 35 return s 36 } 37 38 func ExampleSessionCtx_EnableImplicitlyTransmitAsync() { 39 // EnableImplicitlyTransmitAsync must be true 40 InitDefaultManager(ManagerOptions{ 41 ShardNumber: 10, 42 EnableImplicitlyTransmitAsync: true, 43 GCInterval: time.Hour, 44 }) 45 46 // WARNING: pprof.Do() must be called before BindSession(), 47 // otherwise transparently transmitting session will be dysfunctional 48 labels := pprof.Labels("c", "d") 49 pprof.Do(context.Background(), labels, func(ctx context.Context) {}) 50 51 s := NewSessionMap(map[interface{}]interface{}{ 52 "a": "b", 53 }) 54 BindSession(s) 55 56 // WARNING: pprof.Do() must be called before BindSession(), 57 // otherwise transparently transmitting session will be dysfunctional 58 // labels := pprof.Labels("c", "d") 59 // pprof.Do(context.Background(), labels, func(ctx context.Context){}) 60 61 wg := sync.WaitGroup{} 62 wg.Add(3) 63 go func() { 64 defer wg.Done() 65 ASSERT("b" == mustCurSession().Get("a")) 66 67 go func() { 68 defer wg.Done() 69 ASSERT("b" == mustCurSession().Get("a")) 70 }() 71 72 ASSERT("b" == mustCurSession().Get("a")) 73 UnbindSession() 74 ASSERT(nil == mustCurSession()) 75 76 go func() { 77 defer wg.Done() 78 ASSERT(nil == mustCurSession()) 79 }() 80 81 }() 82 wg.Wait() 83 } 84 85 func ExampleSessionCtx() { 86 // initialize default manager first 87 InitDefaultManager(DefaultManagerOptions()) 88 89 var ctx = context.Background() 90 var key, v = "a", "b" 91 var key2, v2 = "c", "d" 92 var sig = make(chan struct{}) 93 var sig2 = make(chan struct{}) 94 95 // initialize new session with context 96 var session = NewSessionCtx(ctx) // implementation... 97 98 // set specific key-value and update session 99 start := session.WithValue(key, v) 100 101 // set current session 102 BindSession(start) 103 104 // pass to new goroutine... 105 Go(func() { 106 // read specific key under current session 107 val := GetCurSession().Get(key) // val exists 108 ASSERT(val == v) 109 // doSomething.... 110 111 // set specific key-value under current session 112 // NOTICE: current session won't change here 113 next := GetCurSession().WithValue(key2, v2) 114 val2 := GetCurSession().Get(key2) // val2 == nil 115 ASSERT(val2 == nil) 116 117 // pass both parent session and new session to sub goroutine 118 GoSession(next, func() { 119 // read specific key under current session 120 val := GetCurSession().Get(key) // val exists 121 ASSERT(val == v) 122 123 val2 := GetCurSession().Get(key2) // val2 exists 124 ASSERT(val2 == v2) 125 // doSomething.... 126 127 sig2 <- struct{}{} 128 129 <-sig 130 ASSERT(GetCurSession().IsValid() == false) // current session is invalid 131 132 println("g2 done") 133 sig2 <- struct{}{} 134 }) 135 136 Go(func() { 137 // read specific key under current session 138 val := GetCurSession().Get(key) // val exists 139 ASSERT(v == val) 140 141 val2 := GetCurSession().Get(key2) // val2 == nil 142 ASSERT(val2 == nil) 143 // doSomething.... 144 145 sig2 <- struct{}{} 146 147 <-sig 148 ASSERT(GetCurSession().IsValid() == false) // current session is invalid 149 150 println("g3 done") 151 sig2 <- struct{}{} 152 }) 153 154 BindSession(next) 155 val2 = GetCurSession().Get(key2) // val2 exists 156 ASSERT(v2 == val2) 157 158 sig2 <- struct{}{} 159 160 <-sig 161 ASSERT(next.IsValid() == false) // next is invalid 162 163 println("g1 done") 164 sig2 <- struct{}{} 165 }) 166 167 <-sig2 168 <-sig2 169 <-sig2 170 171 val2 := GetCurSession().Get(key2) // val2 == nil 172 ASSERT(val2 == nil) 173 174 // initiatively ends the session, 175 // then all the inherited session (including next) will be disabled 176 session.Disable() 177 close(sig) 178 179 ASSERT(start.IsValid() == false) // start is invalid 180 181 <-sig2 182 <-sig2 183 <-sig2 184 println("g0 done") 185 186 UnbindSession() 187 }