1
2
3
4
5
12 package main
13
14 import (
15 "os"
16 "runtime"
17 "runtime/pprof"
18 "sync"
19 "time"
20 )
21
22 func init() {
23 register("Etcd7492", Etcd7492)
24 }
25
26 type TokenProvider_etcd7492 interface {
27 assign()
28 enable()
29 disable()
30 }
31
32 type simpleTokenTTLKeeper_etcd7492 struct {
33 tokens map[string]time.Time
34 addSimpleTokenCh chan struct{}
35 stopCh chan chan struct{}
36 deleteTokenFunc func(string)
37 }
38
39 type authStore_etcd7492 struct {
40 tokenProvider TokenProvider_etcd7492
41 }
42
43 func (as *authStore_etcd7492) Authenticate() {
44 as.tokenProvider.assign()
45 }
46
47 func NewSimpleTokenTTLKeeper_etcd7492(deletefunc func(string)) *simpleTokenTTLKeeper_etcd7492 {
48 stk := &simpleTokenTTLKeeper_etcd7492{
49 tokens: make(map[string]time.Time),
50 addSimpleTokenCh: make(chan struct{}, 1),
51 stopCh: make(chan chan struct{}),
52 deleteTokenFunc: deletefunc,
53 }
54 go stk.run()
55 return stk
56 }
57
58 func (tm *simpleTokenTTLKeeper_etcd7492) run() {
59 tokenTicker := time.NewTicker(time.Nanosecond)
60 defer tokenTicker.Stop()
61 for {
62 select {
63 case <-tm.addSimpleTokenCh:
64 runtime.Gosched()
65
66 tm.tokens["1"] = time.Now()
67 case <-tokenTicker.C:
68 runtime.Gosched()
69 for t, _ := range tm.tokens {
70 tm.deleteTokenFunc(t)
71 delete(tm.tokens, t)
72 }
73 case waitCh := <-tm.stopCh:
74 waitCh <- struct{}{}
75 return
76 }
77 }
78 }
79
80 func (tm *simpleTokenTTLKeeper_etcd7492) addSimpleToken() {
81 tm.addSimpleTokenCh <- struct{}{}
82 runtime.Gosched()
83 }
84
85 func (tm *simpleTokenTTLKeeper_etcd7492) stop() {
86 waitCh := make(chan struct{})
87 tm.stopCh <- waitCh
88 <-waitCh
89 close(tm.stopCh)
90 }
91
92 type tokenSimple_etcd7492 struct {
93 simpleTokenKeeper *simpleTokenTTLKeeper_etcd7492
94 simpleTokensMu sync.RWMutex
95 }
96
97 func (t *tokenSimple_etcd7492) assign() {
98 t.assignSimpleTokenToUser()
99 }
100
101 func (t *tokenSimple_etcd7492) assignSimpleTokenToUser() {
102 t.simpleTokensMu.Lock()
103 runtime.Gosched()
104 t.simpleTokenKeeper.addSimpleToken()
105 t.simpleTokensMu.Unlock()
106 }
107 func newDeleterFunc(t *tokenSimple_etcd7492) func(string) {
108 return func(tk string) {
109 t.simpleTokensMu.Lock()
110 defer t.simpleTokensMu.Unlock()
111 }
112 }
113
114 func (t *tokenSimple_etcd7492) enable() {
115 t.simpleTokenKeeper = NewSimpleTokenTTLKeeper_etcd7492(newDeleterFunc(t))
116 }
117
118 func (t *tokenSimple_etcd7492) disable() {
119 if t.simpleTokenKeeper != nil {
120 t.simpleTokenKeeper.stop()
121 t.simpleTokenKeeper = nil
122 }
123 t.simpleTokensMu.Lock()
124 t.simpleTokensMu.Unlock()
125 }
126
127 func newTokenProviderSimple_etcd7492() *tokenSimple_etcd7492 {
128 return &tokenSimple_etcd7492{}
129 }
130
131 func setupAuthStore_etcd7492() (store *authStore_etcd7492, teardownfunc func()) {
132 as := &authStore_etcd7492{
133 tokenProvider: newTokenProviderSimple_etcd7492(),
134 }
135 as.tokenProvider.enable()
136 tearDown := func() {
137 as.tokenProvider.disable()
138 }
139 return as, tearDown
140 }
141
142 func Etcd7492() {
143 prof := pprof.Lookup("goroutineleak")
144 defer func() {
145 time.Sleep(100 * time.Millisecond)
146 prof.WriteTo(os.Stdout, 2)
147 }()
148 for i := 0; i < 100; i++ {
149 go func() {
150 as, tearDown := setupAuthStore_etcd7492()
151 defer tearDown()
152 var wg sync.WaitGroup
153 wg.Add(3)
154 for i := 0; i < 3; i++ {
155 go func() {
156 as.Authenticate()
157 defer wg.Done()
158 }()
159 }
160 wg.Wait()
161 }()
162 }
163 }
164
View as plain text