(t *testing.T, nc *nats.Conn)
| 209 | } |
| 210 | |
| 211 | func testContextRequestWithCancel(t *testing.T, nc *nats.Conn) { |
| 212 | ctx, cancelCB := context.WithCancel(context.Background()) |
| 213 | defer cancelCB() // should always be called, not discarded, to prevent context leak |
| 214 | |
| 215 | // timer which cancels the context though can also be arbitrarily extended |
| 216 | expirationTimer := time.AfterFunc(100*time.Millisecond, func() { |
| 217 | cancelCB() |
| 218 | }) |
| 219 | |
| 220 | sub1, err := nc.Subscribe("slow", func(m *nats.Msg) { |
| 221 | // simulates latency into the client so that timeout is hit. |
| 222 | time.Sleep(40 * time.Millisecond) |
| 223 | nc.Publish(m.Reply, []byte("OK")) |
| 224 | }) |
| 225 | if err != nil { |
| 226 | t.Fatalf("Expected to be able to subscribe: %s", err) |
| 227 | } |
| 228 | defer sub1.Unsubscribe() |
| 229 | sub2, err := nc.Subscribe("slower", func(m *nats.Msg) { |
| 230 | // we know this request will take longer so extend the timeout |
| 231 | expirationTimer.Reset(100 * time.Millisecond) |
| 232 | |
| 233 | // slower reply which would have hit original timeout |
| 234 | time.Sleep(70 * time.Millisecond) |
| 235 | |
| 236 | nc.Publish(m.Reply, []byte("Also OK")) |
| 237 | }) |
| 238 | if err != nil { |
| 239 | t.Fatalf("Expected to be able to subscribe: %s", err) |
| 240 | } |
| 241 | defer sub2.Unsubscribe() |
| 242 | |
| 243 | for i := 0; i < 2; i++ { |
| 244 | resp, err := nc.RequestWithContext(ctx, "slow", []byte("")) |
| 245 | if err != nil { |
| 246 | t.Fatalf("Expected request with context to not fail: %s", err) |
| 247 | } |
| 248 | got := string(resp.Data) |
| 249 | expected := "OK" |
| 250 | if got != expected { |
| 251 | t.Errorf("Expected to receive %s, got: %s", expected, got) |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | // A third request with latency would make the context |
| 256 | // get canceled, but these reset the timer so deadline |
| 257 | // gets extended: |
| 258 | for i := 0; i < 10; i++ { |
| 259 | resp, err := nc.RequestWithContext(ctx, "slower", []byte("")) |
| 260 | if err != nil { |
| 261 | t.Fatalf("Expected request with context to not fail: %s", err) |
| 262 | } |
| 263 | got := string(resp.Data) |
| 264 | expected := "Also OK" |
| 265 | if got != expected { |
| 266 | t.Errorf("Expected to receive %s, got: %s", expected, got) |
| 267 | } |
| 268 | } |
no test coverage detected