| 141 | } |
| 142 | |
| 143 | func (e *Example) Get(ctx context.Context, id int64) (*Item, error) { |
| 144 | // 1. enable shadow read from new storage |
| 145 | // ... |
| 146 | // 2. enable priority read from new storage - тоже не совсем корректно, |
| 147 | // т.к. мы ждём старый сторадж, даже если уже выполнился новый - |
| 148 | // нужно установить timeout, иначе запущенную горутину не прибить? |
| 149 | // ... |
| 150 | |
| 151 | errCh := make(chan error) |
| 152 | resultCh := make(chan *Item) |
| 153 | // resultCh1 := make(chan *Item) |
| 154 | // resultCh2 := make(chan *Item) |
| 155 | |
| 156 | ctx, cancel := context.WithCancel(ctx) |
| 157 | defer func() { |
| 158 | cancel() |
| 159 | // close(errCh) |
| 160 | // close(resultCh1) |
| 161 | // close(resultCh2) |
| 162 | }() |
| 163 | |
| 164 | stores := []struct { |
| 165 | source string |
| 166 | store IStore |
| 167 | }{ |
| 168 | {"storeV1", e.storeV1}, |
| 169 | {"storeV2", e.storeV2}, |
| 170 | } |
| 171 | |
| 172 | for _, storeInfo := range stores { |
| 173 | go func(source string, store IStore) { |
| 174 | item, err := store.Get(ctx, id) |
| 175 | println(source) |
| 176 | if err != nil { |
| 177 | errCh <- err |
| 178 | return |
| 179 | } |
| 180 | select { |
| 181 | case resultCh <- item: |
| 182 | // case resultCh1 <- item: |
| 183 | // case resultCh2 <- item: |
| 184 | case <-ctx.Done(): |
| 185 | } |
| 186 | // resultCh <- item |
| 187 | |
| 188 | // switch source { |
| 189 | // case "storeV1": |
| 190 | // resultCh1 <- item |
| 191 | // case "storeV2": |
| 192 | // resultCh2 <- item |
| 193 | // } |
| 194 | }(storeInfo.source, storeInfo.store) |
| 195 | } |
| 196 | |
| 197 | errors := make([]string, 0, len(stores)) |
| 198 | for { |
| 199 | select { |
| 200 | case <-ctx.Done(): |