12c593315Sopenharmony_ci/*
22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library
32c593315Sopenharmony_ci *
42c593315Sopenharmony_ci * Copyright (c) 2012 Tatsuhiro Tsujikawa
52c593315Sopenharmony_ci *
62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining
72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the
82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to
112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
122c593315Sopenharmony_ci * the following conditions:
132c593315Sopenharmony_ci *
142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be
152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software.
162c593315Sopenharmony_ci *
172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
242c593315Sopenharmony_ci */
252c593315Sopenharmony_ci#ifndef SHRPX_DOWNSTREAM_QUEUE_H
262c593315Sopenharmony_ci#define SHRPX_DOWNSTREAM_QUEUE_H
272c593315Sopenharmony_ci
282c593315Sopenharmony_ci#include "shrpx.h"
292c593315Sopenharmony_ci
302c593315Sopenharmony_ci#include <cinttypes>
312c593315Sopenharmony_ci#include <map>
322c593315Sopenharmony_ci#include <set>
332c593315Sopenharmony_ci#include <memory>
342c593315Sopenharmony_ci
352c593315Sopenharmony_ci#include "template.h"
362c593315Sopenharmony_ci
372c593315Sopenharmony_ciusing namespace nghttp2;
382c593315Sopenharmony_ci
392c593315Sopenharmony_cinamespace shrpx {
402c593315Sopenharmony_ci
412c593315Sopenharmony_ciclass Downstream;
422c593315Sopenharmony_ci
432c593315Sopenharmony_ci// Link entry in HostEntry.blocked and downstream because downstream
442c593315Sopenharmony_ci// could be deleted in anytime and we'd like to find Downstream in
452c593315Sopenharmony_ci// O(1).  Downstream has field to link back to this object.
462c593315Sopenharmony_cistruct BlockedLink {
472c593315Sopenharmony_ci  Downstream *downstream;
482c593315Sopenharmony_ci  BlockedLink *dlnext, *dlprev;
492c593315Sopenharmony_ci};
502c593315Sopenharmony_ci
512c593315Sopenharmony_ciclass DownstreamQueue {
522c593315Sopenharmony_cipublic:
532c593315Sopenharmony_ci  struct HostEntry {
542c593315Sopenharmony_ci    HostEntry(ImmutableString &&key);
552c593315Sopenharmony_ci
562c593315Sopenharmony_ci    HostEntry(HostEntry &&) = default;
572c593315Sopenharmony_ci    HostEntry &operator=(HostEntry &&) = default;
582c593315Sopenharmony_ci
592c593315Sopenharmony_ci    HostEntry(const HostEntry &) = delete;
602c593315Sopenharmony_ci    HostEntry &operator=(const HostEntry &) = delete;
612c593315Sopenharmony_ci
622c593315Sopenharmony_ci    // Key that associates this object
632c593315Sopenharmony_ci    ImmutableString key;
642c593315Sopenharmony_ci    // Set of stream ID that blocked by conn_max_per_host_.
652c593315Sopenharmony_ci    DList<BlockedLink> blocked;
662c593315Sopenharmony_ci    // The number of connections currently made to this host.
672c593315Sopenharmony_ci    size_t num_active;
682c593315Sopenharmony_ci  };
692c593315Sopenharmony_ci
702c593315Sopenharmony_ci  using HostEntryMap = std::map<StringRef, HostEntry>;
712c593315Sopenharmony_ci
722c593315Sopenharmony_ci  // conn_max_per_host == 0 means no limit for downstream connection.
732c593315Sopenharmony_ci  DownstreamQueue(size_t conn_max_per_host = 0, bool unified_host = true);
742c593315Sopenharmony_ci  ~DownstreamQueue();
752c593315Sopenharmony_ci  // Add |downstream| to this queue.  This is entry point for
762c593315Sopenharmony_ci  // Downstream object.
772c593315Sopenharmony_ci  void add_pending(std::unique_ptr<Downstream> downstream);
782c593315Sopenharmony_ci  // Set |downstream| to failure state, which means that downstream
792c593315Sopenharmony_ci  // failed to connect to backend.
802c593315Sopenharmony_ci  void mark_failure(Downstream *downstream);
812c593315Sopenharmony_ci  // Set |downstream| to active state, which means that downstream
822c593315Sopenharmony_ci  // connection has started.
832c593315Sopenharmony_ci  void mark_active(Downstream *downstream);
842c593315Sopenharmony_ci  // Set |downstream| to blocked state, which means that download
852c593315Sopenharmony_ci  // connection was blocked because conn_max_per_host_ limit.
862c593315Sopenharmony_ci  void mark_blocked(Downstream *downstream);
872c593315Sopenharmony_ci  // Returns true if we can make downstream connection to given
882c593315Sopenharmony_ci  // |host|.
892c593315Sopenharmony_ci  bool can_activate(const StringRef &host) const;
902c593315Sopenharmony_ci  // Removes and frees |downstream| object.  If |downstream| is in
912c593315Sopenharmony_ci  // DispatchState::ACTIVE, and |next_blocked| is true, this function
922c593315Sopenharmony_ci  // may return Downstream object with the same target host in
932c593315Sopenharmony_ci  // DispatchState::BLOCKED if its connection is now not blocked by
942c593315Sopenharmony_ci  // conn_max_per_host_ limit.
952c593315Sopenharmony_ci  Downstream *remove_and_get_blocked(Downstream *downstream,
962c593315Sopenharmony_ci                                     bool next_blocked = true);
972c593315Sopenharmony_ci  Downstream *get_downstreams() const;
982c593315Sopenharmony_ci  HostEntry &find_host_entry(const StringRef &host);
992c593315Sopenharmony_ci  StringRef make_host_key(const StringRef &host) const;
1002c593315Sopenharmony_ci  StringRef make_host_key(Downstream *downstream) const;
1012c593315Sopenharmony_ci
1022c593315Sopenharmony_ciprivate:
1032c593315Sopenharmony_ci  // Per target host structure to keep track of the number of
1042c593315Sopenharmony_ci  // connections to the same host.
1052c593315Sopenharmony_ci  HostEntryMap host_entries_;
1062c593315Sopenharmony_ci  DList<Downstream> downstreams_;
1072c593315Sopenharmony_ci  // Maximum number of concurrent connections to the same host.
1082c593315Sopenharmony_ci  size_t conn_max_per_host_;
1092c593315Sopenharmony_ci  // true if downstream host is treated as the same.  Used for reverse
1102c593315Sopenharmony_ci  // proxying.
1112c593315Sopenharmony_ci  bool unified_host_;
1122c593315Sopenharmony_ci};
1132c593315Sopenharmony_ci
1142c593315Sopenharmony_ci} // namespace shrpx
1152c593315Sopenharmony_ci
1162c593315Sopenharmony_ci#endif // SHRPX_DOWNSTREAM_QUEUE_H
117