|
276 | 276 | by [clj-http](https://github.com/dakrone/clj-http), and returns a deferred representing
|
277 | 277 | the HTTP response. Also allows for a custom `pool` or `middleware` to be defined.
|
278 | 278 |
|
279 |
| - |:---|:--- |
280 |
| - | `pool` | a custom connection pool |
281 |
| - | `middleware` | custom client middleware for the request |
282 |
| - | `pool-timeout` | timeout in milliseconds for the pool to generate a connection |
283 |
| - | `response-executor` | optional `java.util.concurrent.Executor` that will handle the requests (defaults to a `flow/utilization-executor` of 256 `max-threads` and a `queue-length` of 0) |
284 |
| - | `connection-timeout` | timeout in milliseconds for the connection to become established |
285 |
| - | `request-timeout` | timeout in milliseconds for the arrival of a response over the established connection |
286 |
| - | `read-timeout` | timeout in milliseconds for the response to be completed |
287 |
| - | `follow-redirects?` | whether to follow redirects, defaults to `true`; see `aleph.http.client-middleware/handle-redirects`" |
| 279 | + Param key | Description |
| 280 | + -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 281 | + `connection-timeout` | timeout in milliseconds for the connection to become established |
| 282 | + `follow-redirects?` | whether to follow redirects, defaults to `true`; see `aleph.http.client-middleware/handle-redirects` |
| 283 | + `middleware` | custom client middleware for the request |
| 284 | + `pool-timeout` | timeout in milliseconds for the pool to generate a connection |
| 285 | + `pool` | a custom connection pool |
| 286 | + `read-timeout` | timeout in milliseconds for the response to be completed |
| 287 | + `request-timeout` | timeout in milliseconds for the arrival of a response over the established connection |
| 288 | + `response-executor` | optional `java.util.concurrent.Executor` that will handle the requests (defaults to a `flow/utilization-executor` of 256 `max-threads` and a `queue-length` of 0)" |
288 | 289 | [{:keys [pool
|
289 | 290 | middleware
|
290 | 291 | pool-timeout
|
291 | 292 | response-executor
|
292 | 293 | connection-timeout
|
293 | 294 | request-timeout
|
294 | 295 | read-timeout]
|
295 |
| - :or {pool default-connection-pool |
296 |
| - response-executor default-response-executor |
297 |
| - middleware identity |
298 |
| - connection-timeout 6e4} ;; 60 seconds |
299 |
| - :as req}] |
| 296 | + :or {pool default-connection-pool |
| 297 | + response-executor default-response-executor |
| 298 | + middleware identity |
| 299 | + connection-timeout 6e4} ;; 60 seconds |
| 300 | + :as req}] |
300 | 301 |
|
301 | 302 | (executor/with-executor response-executor
|
302 | 303 | ((middleware
|
|
306 | 307 |
|
307 | 308 | ;; acquire a connection
|
308 | 309 | (-> (flow/acquire pool k)
|
309 |
| - (maybe-timeout! pool-timeout) |
310 |
| - |
311 |
| - ;; pool timeout triggered |
312 |
| - (d/catch' TimeoutException |
313 |
| - (fn [^Throwable e] |
314 |
| - (d/error-deferred (PoolTimeoutException. e)))) |
315 |
| - |
316 |
| - (d/chain' |
317 |
| - (fn [conn] |
318 |
| - |
319 |
| - ;; get the wrapper for the connection, which may or may not be realized yet |
320 |
| - (-> (first conn) |
321 |
| - |
322 |
| - (maybe-timeout! connection-timeout) |
323 |
| - |
324 |
| - ;; connection timeout triggered, dispose of the connetion |
325 |
| - (d/catch' TimeoutException |
326 |
| - (fn [^Throwable e] |
327 |
| - (flow/dispose pool k conn) |
328 |
| - (d/error-deferred (ConnectionTimeoutException. e)))) |
329 |
| - |
330 |
| - ;; connection failed, bail out |
331 |
| - (d/catch' |
332 |
| - (fn [e] |
333 |
| - (flow/dispose pool k conn) |
334 |
| - (d/error-deferred e))) |
335 |
| - |
336 |
| - ;; actually make the request now |
337 |
| - (d/chain' |
338 |
| - |
339 |
| - (fn [conn'] |
340 |
| - |
341 |
| - (when-not (nil? conn') |
342 |
| - (let [end (System/currentTimeMillis)] |
343 |
| - (-> (conn' req) |
344 |
| - (maybe-timeout! request-timeout) |
345 |
| - |
346 |
| - ;; request timeout triggered, dispose of the connection |
347 |
| - (d/catch' TimeoutException |
348 |
| - (fn [^Throwable e] |
349 |
| - (flow/dispose pool k conn) |
350 |
| - (d/error-deferred (RequestTimeoutException. e)))) |
351 |
| - |
352 |
| - ;; request failed, dispose of the connection |
353 |
| - (d/catch' |
354 |
| - (fn [e] |
355 |
| - (flow/dispose pool k conn) |
356 |
| - (d/error-deferred e))) |
357 |
| - |
358 |
| - ;; clean up the response |
359 |
| - (d/chain' |
360 |
| - (fn [rsp] |
361 |
| - |
362 |
| - ;; only release the connection back once the response is complete |
363 |
| - (-> (:aleph/complete rsp) |
364 |
| - (maybe-timeout! read-timeout) |
365 |
| - |
| 310 | + (maybe-timeout! pool-timeout) |
| 311 | + |
| 312 | + ;; pool timeout triggered |
| 313 | + (d/catch' TimeoutException |
| 314 | + (fn [^Throwable e] |
| 315 | + (d/error-deferred (PoolTimeoutException. e)))) |
| 316 | + |
| 317 | + (d/chain' |
| 318 | + (fn [conn] |
| 319 | + |
| 320 | + ;; get the wrapper for the connection, which may or may not be realized yet |
| 321 | + (-> (first conn) |
| 322 | + (maybe-timeout! connection-timeout) |
| 323 | + |
| 324 | + ;; connection timeout triggered, dispose of the connetion |
| 325 | + (d/catch' TimeoutException |
| 326 | + (fn [^Throwable e] |
| 327 | + (flow/dispose pool k conn) |
| 328 | + (d/error-deferred (ConnectionTimeoutException. e)))) |
| 329 | + |
| 330 | + ;; connection failed, bail out |
| 331 | + (d/catch' |
| 332 | + (fn [e] |
| 333 | + (flow/dispose pool k conn) |
| 334 | + (d/error-deferred e))) |
| 335 | + |
| 336 | + ;; actually make the request now |
| 337 | + (d/chain' |
| 338 | + (fn [conn'] |
| 339 | + (when-not (nil? conn') |
| 340 | + (let [end (System/currentTimeMillis)] |
| 341 | + (-> (conn' req) |
| 342 | + (maybe-timeout! request-timeout) |
| 343 | + |
| 344 | + ;; request timeout triggered, dispose of the connection |
366 | 345 | (d/catch' TimeoutException
|
367 | 346 | (fn [^Throwable e]
|
368 | 347 | (flow/dispose pool k conn)
|
369 |
| - (d/error-deferred (ReadTimeoutException. e)))) |
| 348 | + (d/error-deferred (RequestTimeoutException. e)))) |
| 349 | + |
| 350 | + ;; request failed, dispose of the connection |
| 351 | + (d/catch' |
| 352 | + (fn [e] |
| 353 | + (flow/dispose pool k conn) |
| 354 | + (d/error-deferred e))) |
370 | 355 |
|
| 356 | + ;; clean up the connection |
371 | 357 | (d/chain'
|
372 |
| - (fn [early?] |
373 |
| - (if (or early? |
374 |
| - (not (:aleph/keep-alive? rsp)) |
375 |
| - (<= 400 (:status rsp))) |
376 |
| - (flow/dispose pool k conn) |
377 |
| - (flow/release pool k conn))))) |
378 |
| - (-> rsp |
379 |
| - (dissoc :aleph/complete) |
380 |
| - (assoc :connection-time (- end start))))))))) |
381 |
| - |
382 |
| - (fn [rsp] |
383 |
| - (->> rsp |
384 |
| - (middleware/handle-cookies req) |
385 |
| - (middleware/handle-redirects request req))))))))))) |
386 |
| - req)))) |
| 358 | + (fn cleanup-conn [rsp] |
| 359 | + |
| 360 | + ;; only release the connection back once the response is complete |
| 361 | + (-> (:aleph/complete rsp) |
| 362 | + (maybe-timeout! read-timeout) |
| 363 | + |
| 364 | + (d/catch' TimeoutException |
| 365 | + (fn [^Throwable e] |
| 366 | + (flow/dispose pool k conn) |
| 367 | + (d/error-deferred (ReadTimeoutException. e)))) |
| 368 | + |
| 369 | + (d/chain' |
| 370 | + (fn [early?] |
| 371 | + (if (or early? |
| 372 | + (not (:aleph/keep-alive? rsp)) |
| 373 | + (<= 400 (:status rsp))) |
| 374 | + (flow/dispose pool k conn) |
| 375 | + (flow/release pool k conn))))) |
| 376 | + (-> rsp |
| 377 | + (dissoc :aleph/complete) |
| 378 | + (assoc :connection-time (- end start))))))))) |
| 379 | + |
| 380 | + (fn handle-response [rsp] |
| 381 | + (->> rsp |
| 382 | + (middleware/handle-cookies req) |
| 383 | + (middleware/handle-redirects request req))))))))))) |
| 384 | + req)))) |
387 | 385 |
|
388 | 386 | (defn- req
|
389 | 387 | ([method url]
|
|
0 commit comments