Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test-npm failing on master after introduction of initial async hooks implementation #13045

Closed
mscdex opened this issue May 16, 2017 · 13 comments · Fixed by #13092 or #13839
Closed

test-npm failing on master after introduction of initial async hooks implementation #13045

mscdex opened this issue May 16, 2017 · 13 comments · Fixed by #13092 or #13839
Assignees
Labels
async_hooks Issues and PRs related to the async hooks subsystem. confirmed-bug Issues with confirmed bugs. regression Issues related to regressions.

Comments

@mscdex
Copy link
Contributor

mscdex commented May 16, 2017

  • Version: master
  • Platform: n/a
  • Subsystem: async_hooks

make test-npm is failing since #12892 (4a7233c) landed it seems. In particular, it appears that it's possible for a socket handle to not have an asyncReset function attached (perhaps something in npm or one of its dependencies are unsetting it?), causing a TypeError on this line.

After running across that issue, I spotted just a few lines below that that there is a bug waiting to happen on this line and this line because newSocket should be undefined if an error occurred.

I have not checked for other similar potential issues yet.

/cc @AndreasMadsen @addaleax @trevnorris

@mscdex mscdex added async_hooks Issues and PRs related to the async hooks subsystem. confirmed-bug Issues with confirmed bugs. labels May 16, 2017
@refack refack self-assigned this May 16, 2017
@refack
Copy link
Contributor

refack commented May 16, 2017

I'll try to distill this into a test case.

@refack refack added the regression Issues related to regressions. label May 16, 2017
@Fishrock123
Copy link
Contributor

Hmmm, this is not new.

I debugged this 2-3 times with @trevnorris over the course of Async Hooks' development. I was pretty sure it was fixed, though.

@AndreasMadsen AndreasMadsen self-assigned this May 16, 2017
@trevnorris
Copy link
Contributor

I've run into this elsewhere. Thought I traced through core code well enough to be confident those checks could be removed, but apparently that's not the case. Only way I've found that can definitely mitigate this issue is to check if the call is actually a function. If someone has a better idea I'm all ears. Otherwise I can write up a PR to fix this.

@AndreasMadsen
Copy link
Member

@trevnorris what causes the issue?

@trevnorris
Copy link
Contributor

@AndreasMadsen from what I've seen it usually happens when users fake the _handle, but in this case it can also be from a user supplied Agent instance that isn't attached to an internal node resource.

@refack
Copy link
Contributor

refack commented May 18, 2017

I have an almost minimal (depends on request) failing test:

'use strict'
var https = require('https')
var request = require('request')
var opt = {
  agent: new https.Agent({
    'keepAlive': true,
    'maxSockets': 50,
    'rejectUnauthorized': true,
  }),
  uri: 'https://www.google.com/'
}

request(opt, (error, response, data) => {
  console.log(`error: ${error}`)
  console.log(`response: ${response}`)
  console.log(`data.length: ${data && data.length}`)
  request(opt, (error, response, data) => {
    console.log(`error: ${error}`)
    console.log(`response: ${response}`)
  console.log(`data.length: ${data && data.length}`)
  });
});

Still request uses the Agent better then I managed...

@refack
Copy link
Contributor

refack commented May 18, 2017

@trevnorris question: in 7e3a3c9 why did only tcp_wrap get a asyncReset JS function?

After running across that issue, I spotted just a few lines below that that there is a bug waiting to happen on this line and this line because newSocket should be undefined if an error occurred.

P.S. @mscdex those cases work, newSocket is created (didn't think of the err case... midnight brain 😴 )

@mscdex
Copy link
Contributor Author

mscdex commented May 18, 2017

After running across that issue, I spotted just a few lines below that that there is a bug waiting to happen on this line and this line because newSocket should be undefined if an error occurred.

P.S. @mscdex those cases work, newSocket is created

@refack That's not true. Custom async createConnection() implementations can pass an error and in that case there is no socket.

@refack
Copy link
Contributor

refack commented May 18, 2017

@refack That's not true. Custom async createConnection() implementations can pass an error and in that case there is no socket.

Gottcha... 👍

@refack
Copy link
Contributor

refack commented May 18, 2017

minimal failing test

'use strict'
var https = require('https')
var options = {
  agent: new https.Agent({
    'keepAlive': true,
    'maxSockets': 50,
    'rejectUnauthorized': true,
  }),
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET'
}

const req = https.request(options, (res) => {
  console.log('statusCode:', res.statusCode)

  res.on('error', (e) => {
    console.error(e)
  })

  let ret = ''
  res.on('data', (d) => { ret += d })

  res.socket.on('free', (hadErr) => {
    console.log(`hadErr ${hadErr}`)
    console.log(`ret.length ${ret.length}`)

    const req2 = https.request(options)
  })
})

req.end();

Output

statusCode: 200
hadErr undefined
ret.length 41688
_http_agent.js:170
    socket._handle.asyncReset();
                   ^

TypeError: socket._handle.asyncReset is not a function
    at Agent.addRequest (_http_agent.js:170:20)
    at new ClientRequest (_http_client.js:269:16)
    at Object.request (http.js:39:10)
    at Object.request (https.js:230:15)
    at TLSSocket.res.socket.on (D:\code\tools\tmp\test-utl.js:29:24)
    at emitNone (events.js:110:20)
    at TLSSocket.emit (events.js:207:7)
    at emitFreeNT (_http_client.js:621:10)
    at _combinedTickCallback (internal/process/next_tick.js:99:11)
    at process._tickCallback (internal/process/next_tick.js:161:9)

Process finished with exit code 1

IMHO since it's a TLS connection, the Agent tries to reuse a TLSSocket, and the TLSWrap doesn't have an asyncReset method

@refack refack removed their assignment May 18, 2017
refack added a commit to refack/node that referenced this issue May 20, 2017
When using an Agent for HTTPS, `TLSSocket`s are reused and need to
have the ability to `asyncReset` from JS.

PR-URL: nodejs#13092
Fixes: nodejs#13045
Reviewed-By: Andreas Madsen <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
@mscdex mscdex reopened this Jun 21, 2017
@mscdex
Copy link
Contributor Author

mscdex commented Jun 21, 2017

The second part of this issue seems to still exist and was not solved by #13092. We now have users hitting that issue: #13831

@mscdex
Copy link
Contributor Author

mscdex commented Jun 21, 2017

/cc @nodejs/async_hooks

@refack
Copy link
Contributor

refack commented Jun 21, 2017

There was further discussion on the "broken" Agent story in #13548 (comment)

refack added a commit to refack/node that referenced this issue Jul 3, 2017
addaleax pushed a commit to addaleax/node that referenced this issue Jul 3, 2017
addaleax pushed a commit that referenced this issue Jul 11, 2017
PR-URL: #13839
Fixes: #13045
Fixes: #13831
Refs: #13352
Refs: #13548 (comment)
Reviewed-By: Trevor Norris <[email protected]>
addaleax pushed a commit that referenced this issue Jul 18, 2017
PR-URL: #13839
Fixes: #13045
Fixes: #13831
Refs: #13352
Refs: #13548 (comment)
Reviewed-By: Trevor Norris <[email protected]>
Fishrock123 pushed a commit that referenced this issue Jul 19, 2017
PR-URL: #13839
Fixes: #13045
Fixes: #13831
Refs: #13352
Refs: #13548 (comment)
Reviewed-By: Trevor Norris <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
async_hooks Issues and PRs related to the async hooks subsystem. confirmed-bug Issues with confirmed bugs. regression Issues related to regressions.
Projects
None yet
5 participants