DoChan is like Do but returns a channel that will receive the results when they are ready. The returned channel will not be closed.
(key K, fn func() (V, error))
| 122 | // |
| 123 | // The returned channel will not be closed. |
| 124 | func (g *Group[K, V]) DoChan(key K, fn func() (V, error)) <-chan Result[V] { |
| 125 | ch := make(chan Result[V], 1) |
| 126 | g.mu.Lock() |
| 127 | if g.m == nil { |
| 128 | g.m = make(map[K]*call[V]) |
| 129 | } |
| 130 | if c, ok := g.m[key]; ok { |
| 131 | c.dups++ |
| 132 | c.chans = append(c.chans, ch) |
| 133 | g.mu.Unlock() |
| 134 | return ch |
| 135 | } |
| 136 | c := &call[V]{chans: []chan<- Result[V]{ch}} |
| 137 | c.wg.Add(1) |
| 138 | g.m[key] = c |
| 139 | g.mu.Unlock() |
| 140 | |
| 141 | go g.doCall(c, key, fn) |
| 142 | |
| 143 | return ch |
| 144 | } |
| 145 | |
| 146 | // doCall handles the single call for a key. |
| 147 | func (g *Group[K, V]) doCall(c *call[V], key K, fn func() (V, error)) { |