Skip to content

Commit

Permalink
fix(http2): Unref stale session (marked for destruction)
Browse files Browse the repository at this point in the history
  • Loading branch information
grantila committed Jan 14, 2019
1 parent 6b526ea commit e130ce2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
35 changes: 23 additions & 12 deletions lib/context-http2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ import {
import { Request } from "./request";
import { Response, StreamResponse } from "./response";
import { makeOkError } from "./utils";
import { setGotGoaway } from "./utils-http2";
import {
isDestroyed,
MonkeyH2Session,
setDestroyed,
setGotGoaway,
} from "./utils-http2";


const {
Expand Down Expand Up @@ -171,24 +176,29 @@ export class H2Context

public deleteActiveSession( origin: string ): H2SessionItem | void
{
if ( !this._h2sessions.has( origin ) )
const sessionItem = this._h2sessions.get( origin );

if ( !sessionItem )
return;

const sessionItem = this._h2sessions.get( origin );
this._h2sessions.delete( origin );

sessionItem.session.unref( );
// Never re-ref, this session is over
setDestroyed( sessionItem.session );

return sessionItem;
}

public async disconnectStaleSessions( origin: string ): Promise< void >
{
const promises: Array< Promise< void > > = [ ];

if ( !this._h2staleSessions.has( origin ) )
const sessionSet = this._h2staleSessions.get( origin );

if ( !sessionSet )
return;

const sessionSet =
< Set< ClientHttp2Session > >this._h2staleSessions.get( origin );
this._h2staleSessions.delete( origin );

for ( const session of sessionSet )
Expand Down Expand Up @@ -348,24 +358,25 @@ export class H2Context

const makeRefs = ( session: ClientHttp2Session ) =>
{
let counter = 1; // Begins ref'd
const monkeySession = < MonkeyH2Session >session;
monkeySession.__fetch_h2_refcount = 1; // Begins ref'd
sessionRefs.ref = ( ) =>
{
if ( session.destroyed )
if ( isDestroyed( session ) )
return;

if ( counter === 0 )
if ( monkeySession.__fetch_h2_refcount === 0 )
// Go from unref'd to ref'd
session.ref( );
++counter;
++monkeySession.__fetch_h2_refcount;
};
sessionRefs.unref = ( ) =>
{
if ( session.destroyed )
return;

--counter;
if ( counter === 0 )
--monkeySession.__fetch_h2_refcount;
if ( monkeySession.__fetch_h2_refcount === 0 )
// Go from ref'd to unref'd
session.unref( );
};
Expand Down
23 changes: 21 additions & 2 deletions lib/utils-http2.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import { ClientHttp2Session } from "http2";


export interface MonkeyH2Session extends ClientHttp2Session
{
__fetch_h2_destroyed?: boolean;
__fetch_h2_goaway?: boolean;
__fetch_h2_refcount: number;
}

export function hasGotGoaway( session: ClientHttp2Session )
{
return !!( < any >session ).__fetch_h2_goaway;
return !!( < MonkeyH2Session >session ).__fetch_h2_goaway;
}

export function setGotGoaway( session: ClientHttp2Session )
{
( < any >session ).__fetch_h2_goaway = true;
( < MonkeyH2Session >session ).__fetch_h2_goaway = true;
}

export function isDestroyed( session: ClientHttp2Session )
{
const monkeySession = < MonkeyH2Session >session;
return monkeySession.destroyed || monkeySession.__fetch_h2_destroyed;
}

export function setDestroyed( session: ClientHttp2Session )
{
( < MonkeyH2Session >session ).__fetch_h2_destroyed = true;
}

0 comments on commit e130ce2

Please sign in to comment.