http2: only schedule write when necessary · nodejs/node@fe5ec8e · GitHub
Skip to content

Commit fe5ec8e

Browse files
addaleaxMylesBorins
authored andcommitted
http2: only schedule write when necessary
Introduce an `Http2Scope` class that, when it goes out of scope, checks whether a write to the network is desired by nghttp2. If that is the case, schedule a write using `SetImmediate()` rather than a custom per-session libuv handle. Backport-PR-URL: #18050 PR-URL: #17183 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
1 parent d678541 commit fe5ec8e

3 files changed

Lines changed: 114 additions & 41 deletions

File tree

src/node_http2.cc

Lines changed: 61 additions & 40 deletions

src/node_http2.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,9 @@ const char* nghttp2_errname(int rv) {
417417

418418
enum session_state_flags {
419419
SESSION_STATE_NONE = 0x0,
420-
SESSION_STATE_DESTROYING = 0x1
420+
SESSION_STATE_DESTROYING = 0x1,
421+
SESSION_STATE_HAS_SCOPE = 0x2,
422+
SESSION_STATE_WRITE_SCHEDULED = 0x4
421423
};
422424

423425
// This allows for 4 default-sized frames with their frame headers
@@ -429,6 +431,19 @@ typedef uint32_t(*get_setting)(nghttp2_session* session,
429431
class Http2Session;
430432
class Http2Stream;
431433

434+
// This scope should be present when any call into nghttp2 that may schedule
435+
// data to be written to the underlying transport is made, and schedules
436+
// such a write automatically once the scope is exited.
437+
class Http2Scope {
438+
public:
439+
explicit Http2Scope(Http2Stream* stream);
440+
explicit Http2Scope(Http2Session* session);
441+
~Http2Scope();
442+
443+
private:
444+
Http2Session* session_ = nullptr;
445+
};
446+
432447
// The Http2Options class is used to parse the options object passed in to
433448
// a Http2Session object and convert those into an appropriate nghttp2_option
434449
// struct. This is the primary mechanism by which the Http2Session object is
@@ -815,6 +830,9 @@ class Http2Session : public AsyncWrap {
815830
inline void MarkDestroying() { flags_ |= SESSION_STATE_DESTROYING; }
816831
inline bool IsDestroying() { return flags_ & SESSION_STATE_DESTROYING; }
817832

833+
// Schedule a write if nghttp2 indicates it wants to write to the socket.
834+
void MaybeScheduleWrite();
835+
818836
// Returns pointer to the stream, or nullptr if stream does not exist
819837
inline Http2Stream* FindStream(int32_t id);
820838

@@ -1004,6 +1022,8 @@ class Http2Session : public AsyncWrap {
10041022

10051023
size_t max_outstanding_pings_ = DEFAULT_MAX_PINGS;
10061024
std::queue<Http2Ping*> outstanding_pings_;
1025+
1026+
friend class Http2Scope;
10071027
};
10081028

10091029
class Http2Session::Http2Ping : public AsyncWrap {
Lines changed: 32 additions & 0 deletions

0 commit comments

Comments
 (0)