File: http2_stream_manager_impl.h

package info (click to toggle)
aws-crt-python 0.20.4%2Bdfsg-1~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 72,656 kB
  • sloc: ansic: 381,805; python: 23,008; makefile: 6,251; sh: 4,536; cpp: 699; ruby: 208; java: 77; perl: 73; javascript: 46; xml: 11
file content (199 lines) | stat: -rw-r--r-- 8,394 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#ifndef AWS_HTTP2_STREAM_MANAGER_IMPL_H
#define AWS_HTTP2_STREAM_MANAGER_IMPL_H

/**
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

#include <aws/common/mutex.h>
#include <aws/common/ref_count.h>
#include <aws/http/http2_stream_manager.h>
#include <aws/http/private/random_access_set.h>

enum aws_h2_sm_state_type {
    AWS_H2SMST_READY,
    AWS_H2SMST_DESTROYING, /* On zero external ref count, can destroy */
};

enum aws_h2_sm_connection_state_type {
    AWS_H2SMCST_IDEAL,
    AWS_H2SMCST_NEARLY_FULL,
    AWS_H2SMCST_FULL,
};

/* Live with the streams opening, and if there no outstanding pending acquisition and no opening streams on the
 * connection, this structure should die */
struct aws_h2_sm_connection {
    struct aws_allocator *allocator;
    struct aws_http2_stream_manager *stream_manager;
    struct aws_http_connection *connection;
    uint32_t num_streams_assigned;   /* From a stream assigned to the connection until the stream completed
                                                     or failed to be created from the connection. */
    uint32_t max_concurrent_streams; /* lower bound between user configured and the other side */

    /* task to send ping periodically from connection thread. */
    struct aws_ref_count ref_count;
    struct aws_channel_task ping_task;
    struct aws_channel_task ping_timeout_task;
    struct {
        bool ping_received;
        bool stopped_new_requests;
        uint64_t next_ping_task_time;
    } thread_data;

    enum aws_h2_sm_connection_state_type state;
};

/* Live from the user request to acquire a stream to the stream completed. */
struct aws_h2_sm_pending_stream_acquisition {
    struct aws_allocator *allocator;
    struct aws_linked_list_node node;
    struct aws_http_make_request_options options;
    struct aws_h2_sm_connection *sm_connection; /* The connection to make request to. Keep
                                               NULL, until find available one and move it to the pending_make_requests
                                               list. */
    struct aws_http_message *request;
    struct aws_channel_task make_request_task;
    aws_http2_stream_manager_on_stream_acquired_fn *callback;
    void *user_data;
};

/* connections_acquiring_count, open_stream_count, pending_make_requests_count AND pending_stream_acquisition_count */
enum aws_sm_count_type {
    AWS_SMCT_CONNECTIONS_ACQUIRING,
    AWS_SMCT_OPEN_STREAM,
    AWS_SMCT_PENDING_MAKE_REQUESTS,
    AWS_SMCT_PENDING_ACQUISITION,
    AWS_SMCT_COUNT,
};

struct aws_http2_stream_manager {
    struct aws_allocator *allocator;
    void *shutdown_complete_user_data;
    aws_http2_stream_manager_shutdown_complete_fn *shutdown_complete_callback;
    /**
     * Underlying connection manager. Always has the same life time with the stream manager who owns it.
     */
    struct aws_http_connection_manager *connection_manager;
    /**
     * Refcount managed by user. Once this drops to zero, the manager state transitions to shutting down
     */
    struct aws_ref_count external_ref_count;
    /**
     * Internal refcount that keeps connection manager alive.
     *
     * It's a sum of connections_acquiring_count, open_stream_count, pending_make_requests_count and
     * pending_stream_acquisition_count, besides the number of `struct aws_http2_stream_management_transaction` alive.
     * And one for external usage.
     *
     * Once this refcount drops to zero, stream manager should either be cleaned up all the memory all waiting for
     * the last task to clean un the memory and do nothing else.
     */
    struct aws_ref_count internal_ref_count;
    struct aws_client_bootstrap *bootstrap;

    /* Configurations */
    size_t max_connections;
    /* Connection will be closed if 5xx response received from server. */
    bool close_connection_on_server_error;

    uint64_t connection_ping_period_ns;
    uint64_t connection_ping_timeout_ns;

    /**
     * Default is no limit. 0 will be considered as using the default value.
     * The ideal number of concurrent streams for a connection. Stream manager will try to create a new connection if
     * one connection reaches this number. But, if the max connections reaches, manager will reuse connections to create
     * the acquired steams as much as possible. */
    size_t ideal_concurrent_streams_per_connection;
    /**
     * Default is no limit. 0 will be considered as using the default value.
     * The real number of concurrent streams per connection will be controlled by the minmal value of the setting from
     * other end and the value here.
     */
    size_t max_concurrent_streams_per_connection;

    /**
     * Task to invoke pending acquisition callbacks asynchronously if stream manager is shutting.
     */
    struct aws_event_loop *finish_pending_stream_acquisitions_task_event_loop;

    /* Any thread may touch this data, but the lock must be held (unless it's an atomic) */
    struct {
        struct aws_mutex lock;
        /*
         * A manager can be in one of two states, READY or SHUTTING_DOWN.  The state transition
         * takes place when ref_count drops to zero.
         */
        enum aws_h2_sm_state_type state;

        /**
         * A set of all connections that meet all requirement to use. Note: there will be connections not in this set,
         * but hold by the stream manager, which can be tracked by the streams created on it. Set of `struct
         * aws_h2_sm_connection *`
         */
        struct aws_random_access_set ideal_available_set;
        /**
         * A set of all available connections that exceed the soft limits set by users. Note: there will be connections
         * not in this set, but hold by the stream manager, which can be tracked by the streams created. Set of `struct
         * aws_h2_sm_connection *`
         */
        struct aws_random_access_set nonideal_available_set;
        /* We don't mantain set for connections that is full or "dead" (Cannot make any new streams). We have streams
         * opening from the connection tracking them */

        /**
         * The set of all incomplete stream acquisition requests (haven't decide what connection to make the request
         * to), list of `struct aws_h2_sm_pending_stream_acquisition*`
         */
        struct aws_linked_list pending_stream_acquisitions;

        /**
         * The number of connections acquired from connection manager and not released yet.
         */
        size_t holding_connections_count;

        /**
         * Counts that contributes to the internal refcount.
         * When the value changes, s_sm_count_increase/decrease_synced needed.
         *
         * AWS_SMCT_CONNECTIONS_ACQUIRING: The number of new connections we acquiring from the connection manager.
         * AWS_SMCT_OPEN_STREAM: The number of streams that opened and not completed yet.
         * AWS_SMCT_PENDING_MAKE_REQUESTS: The number of streams that scheduled to be made from a connection but haven't
         *      been executed yet.
         * AWS_SMCT_PENDING_ACQUISITION:  The number of all incomplete stream acquisition requests (haven't decide what
         *      connection to make the request to). So that we don't have compute the size of a linked list every time.
         */
        size_t internal_refcount_stats[AWS_SMCT_COUNT];

        bool finish_pending_stream_acquisitions_task_scheduled;
    } synced_data;
};

/**
 * Encompasses all of the external operations that need to be done for various
 * events:
 *  - User level:
 *   stream manager release
 *   stream acquire
 *  - Internal eventloop (anther thread):
 *   connection_acquired
 *   stream_completed
 *  - Internal (can happen from any thread):
 *   connection acquire
 *   connection release
 *
 * The transaction is built under the manager's lock (and the internal state is updated optimistically),
 * but then executed outside of it.
 */
struct aws_http2_stream_management_transaction {
    struct aws_http2_stream_manager *stream_manager;
    struct aws_allocator *allocator;
    size_t new_connections;
    struct aws_h2_sm_connection *sm_connection_to_release;
    struct aws_linked_list
        pending_make_requests; /* List of aws_h2_sm_pending_stream_acquisition with chosen connection */
};

#endif /* AWS_HTTP2_STREAM_MANAGER_IMPL_H */