1/*
2 * nghttp2 - HTTP/2 C Library
3 *
4 * Copyright (c) 2012 Tatsuhiro Tsujikawa
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25#ifndef SHRPX_DOWNSTREAM_QUEUE_H
26#define SHRPX_DOWNSTREAM_QUEUE_H
27
28#include "shrpx.h"
29
30#include <cinttypes>
31#include <map>
32#include <set>
33#include <memory>
34
35#include "template.h"
36
37using namespace nghttp2;
38
39namespace shrpx {
40
41class Downstream;
42
43// Link entry in HostEntry.blocked and downstream because downstream
44// could be deleted in anytime and we'd like to find Downstream in
45// O(1).  Downstream has field to link back to this object.
46struct BlockedLink {
47  Downstream *downstream;
48  BlockedLink *dlnext, *dlprev;
49};
50
51class DownstreamQueue {
52public:
53  struct HostEntry {
54    HostEntry(ImmutableString &&key);
55
56    HostEntry(HostEntry &&) = default;
57    HostEntry &operator=(HostEntry &&) = default;
58
59    HostEntry(const HostEntry &) = delete;
60    HostEntry &operator=(const HostEntry &) = delete;
61
62    // Key that associates this object
63    ImmutableString key;
64    // Set of stream ID that blocked by conn_max_per_host_.
65    DList<BlockedLink> blocked;
66    // The number of connections currently made to this host.
67    size_t num_active;
68  };
69
70  using HostEntryMap = std::map<StringRef, HostEntry>;
71
72  // conn_max_per_host == 0 means no limit for downstream connection.
73  DownstreamQueue(size_t conn_max_per_host = 0, bool unified_host = true);
74  ~DownstreamQueue();
75  // Add |downstream| to this queue.  This is entry point for
76  // Downstream object.
77  void add_pending(std::unique_ptr<Downstream> downstream);
78  // Set |downstream| to failure state, which means that downstream
79  // failed to connect to backend.
80  void mark_failure(Downstream *downstream);
81  // Set |downstream| to active state, which means that downstream
82  // connection has started.
83  void mark_active(Downstream *downstream);
84  // Set |downstream| to blocked state, which means that download
85  // connection was blocked because conn_max_per_host_ limit.
86  void mark_blocked(Downstream *downstream);
87  // Returns true if we can make downstream connection to given
88  // |host|.
89  bool can_activate(const StringRef &host) const;
90  // Removes and frees |downstream| object.  If |downstream| is in
91  // DispatchState::ACTIVE, and |next_blocked| is true, this function
92  // may return Downstream object with the same target host in
93  // DispatchState::BLOCKED if its connection is now not blocked by
94  // conn_max_per_host_ limit.
95  Downstream *remove_and_get_blocked(Downstream *downstream,
96                                     bool next_blocked = true);
97  Downstream *get_downstreams() const;
98  HostEntry &find_host_entry(const StringRef &host);
99  StringRef make_host_key(const StringRef &host) const;
100  StringRef make_host_key(Downstream *downstream) const;
101
102private:
103  // Per target host structure to keep track of the number of
104  // connections to the same host.
105  HostEntryMap host_entries_;
106  DList<Downstream> downstreams_;
107  // Maximum number of concurrent connections to the same host.
108  size_t conn_max_per_host_;
109  // true if downstream host is treated as the same.  Used for reverse
110  // proxying.
111  bool unified_host_;
112};
113
114} // namespace shrpx
115
116#endif // SHRPX_DOWNSTREAM_QUEUE_H
117