clj-commons / clj-commons/aleph

Support cancellation of HTTP requests

Open
#712 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Clojure
Stars
2.6k
Forks
242
Avg merge
4d 5h
Merged PRs (30d)
1

Description

# Problem

At the moment it is not possible to cancel HTTP requests (be it in-flight or during connection establishment). The only option users have is to just drop the response deferred on the floor and have it GC'ed. However, this doesn't free up the underlying connection until the response is complete. Combined with the fact that there is no default `request-timeout`, this can lead to resource exhaustion.

Manifold's idiom for cancelling a deferred is to put it into an error state but that only affects *chained* deferreds downstream from the "cancelled" one (see also https://github.com/clj-commons/manifold/issues/167). Since the response deferred returned by `aleph.http/request` sits at the very end of the deferred chain, putting it into an error state has no repercussion on any of the upstream deferreds nor on the underlying connection.

This also means that placing a timeout on a response deferred to limit the overall request duration (i.e. connection setup, request transmission and response reception) doesn't have the effect a user might expect:

```clojure
@(-> (http/get "...") (d/timeout! 1000))
```

As explained above, this will simply put the response deferred into an error state when the timeout expires but the underlying request operation will still proceed, tying up any resources it has acquired until done.

# Solutions

The most elegant solution would be to change Manifold to also cancel any upstream deferreds which feed into a "cancelled" deferred (if there are no others left). However, [according to Zach](https://github.com/clj-commons/manifold/issues/166#issuecomment-459902958), this cannot be implemented in the current architecture of Manifold and would require a "major reengineering".

A more tractable solution would be to explicitly cancel any upstream operations when the response deferred is set into an error state.

Contributor guide

Open the contributing guide

Research direction

Start at the aleph.http/request entry point and review the linked Manifold cancellation discussion, including issues 166 and 167. Done means cancelling or timing out the response also cancels upstream operations and releases the underlying connection during connection establishment or an in-flight request.

Written by the indexing model from the issue text.

Assessment

Tech stack
clojure
Domain
api, networking
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.