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

Hang: Second request to same URL immediately after first #10570

Open
scottnonnenberg opened this Issue Sep 21, 2017 · 6 comments

Comments

Projects
None yet
5 participants
@scottnonnenberg

scottnonnenberg commented Sep 21, 2017

  • Electron version: 1.8.0, 1.6.13, and 1.6.7
  • Operating system: Ubuntu 16.04 (no repro on OSX 10.11.6)

Expected behavior

Two repeated requests to the same URL from the renderer process via Node.js APIs come back with responses. On OSX this happens properly.

Actual behavior

On Linux, if a second request is made right after the first one finishes, that second request will start but not finish. Strangely, it can be forced to come back later with another request.

How to reproduce

Put this code in your preload.js file and start Electron:

var https = require('https');

var _setImmediate = setImmediate;
process.once('loaded', function() {
  window.setImmediate = _setImmediate;
});

function makeRequest(cb) {
  if (!cb) {
    cb = function() {}
  }

  console.log('making request');
  var options = {
    host: 'github.com',
    port: 443,
    path: '/',
    method: 'GET',
    agent: new https.Agent()
  };
  var req = https.request(options, (res) => {
    console.log('request/statusCode:', res.statusCode);
    console.log('request/headers:', res.headers);

    res.on('data', (d) => {
      console.log('data', d.toString().length);
    });
    res.on('end', () => {
      console.log('No more data in response.');
      return cb();
    });
  });

  req.on('request/error', (e) => {
    console.error(e);
    return cb();
  });
  req.end();
}


makeRequest(function() {
  makeRequest();
});

if (typeof window !== 'undefined') {
  window.makeRequest = makeRequest;
}

On Linux the final log entry is making request because the second request hangs. On Electron 1.8.0, the DevTools disconnect a bit later, and you get a 'Check failed' log to the console (see the details below). On previous versions of Electron, neither of those two things happen.

You can call window.makeRequest() later and see two responses come back. This appears to 'wake up' the Node.js side.

Other things tried

  • Direct call of this code from Node.js 7.4.0 on Linux and OSX. No repro.
  • Direct load from Electron entrypoint (the one that calls createWindow). No repro.
  • Load of this code via require() and remote.require() from preload.js. Still happened.
  • Looked at the logging that came from NODE_DEBUG=http, and key events are not fired when this issue repros, even at that level
  • Tried it on windows both in Electron and in Node.js. No repro.
The check failed log entry on Electron 1.8.0:
[22179:0921/130510.974808:FATAL:partition_alloc.cc(934)] Check failed: page->num_allocated_slots != -1. 
#0 0x000001deb897 <unknown>
#1 0x000001e163ab <unknown>
#2 0x000001dcfeb5 <unknown>
#3 0x000001d3045d <unknown>
#4 0x7f31a7178b43 <unknown>
#5 0x7f31a70ebeb2 <unknown>
#6 0x7f31a70f7a71 <unknown>
#7 0x7f31a70eccfe <unknown>
#8 0x7f31a70e5657 <unknown>
#9 0x7f31a70e3059 <unknown>
#10 0x7f31a6bc6523 <unknown>
#11 0x7f31a6bc4b7a <unknown>
#12 0x7f31a6bc40f4 <unknown>
#13 0x7f31a6bd2996 <unknown>
#14 0x7f31a6ef9fb3 <unknown>
#15 0x000001e03660 <unknown>
#16 0x000001c8cef8 <unknown>
#17 0x000001c8b198 <unknown>
#18 0x000001e03660 <unknown>
#19 0x000001df688d <unknown>
#20 0x000001df6ba8 <unknown>
#21 0x000001df7246 <unknown>
#22 0x000001e080ea <unknown>
#23 0x000001df65b7 <unknown>
#24 0x000001e5476e <unknown>
#25 0x00000302d350 <unknown>
#26 0x0000031721aa <unknown>
#27 0x000003173048 <unknown>
#28 0x0000029e111f <unknown>
#29 0x000003171ec2 <unknown>
#30 0x000003de1168 main
#31 0x7f319f94b830 __libc_start_main
#32 0x0000005a5099 <unknown>

DevTools disconnect on Electron 1.8.0:
screen shot 2017-09-21 at 10 07 57 am

@welcome

This comment has been minimized.

Show comment
Hide comment
@welcome

welcome bot Sep 21, 2017

👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

To help make it easier for us to investigate your issue, please follow the contributing guidelines.

welcome bot commented Sep 21, 2017

👋 Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

To help make it easier for us to investigate your issue, please follow the contributing guidelines.

@scottnonnenberg

This comment has been minimized.

Show comment
Hide comment
@scottnonnenberg

scottnonnenberg Sep 21, 2017

You might be wondering why we're trying to use Node.js APIs for making web requests in the renderer process - it's because we can provide our own certificate authority.

I'm really not sure where to go next. I was thinking that we could move all of our web requests into the main process and rely on IPC to get that data to the renderer process, but that's a pretty big change for our app. Any thoughts?

scottnonnenberg commented Sep 21, 2017

You might be wondering why we're trying to use Node.js APIs for making web requests in the renderer process - it's because we can provide our own certificate authority.

I'm really not sure where to go next. I was thinking that we could move all of our web requests into the main process and rely on IPC to get that data to the renderer process, but that's a pretty big change for our app. Any thoughts?

scottnonnenberg added a commit to scottnonnenberg/electron-hang-repro that referenced this issue Sep 21, 2017

@scottnonnenberg

This comment has been minimized.

Show comment
Hide comment
@scottnonnenberg

scottnonnenberg Sep 21, 2017

The plot thickens:

I tested this on Windows 10, and it doesn't happen.

My repository for testing it in a pristine state does NOT show the behavior: https://github.com/scottnonnenberg/electron-hang-repro

What does show the behavior is the electron app here: https://github.com/WhisperSystems/Signal-Desktop/tree/v1.0.25

Next on my list: figure out the difference between which causes this.

scottnonnenberg commented Sep 21, 2017

The plot thickens:

I tested this on Windows 10, and it doesn't happen.

My repository for testing it in a pristine state does NOT show the behavior: https://github.com/scottnonnenberg/electron-hang-repro

What does show the behavior is the electron app here: https://github.com/WhisperSystems/Signal-Desktop/tree/v1.0.25

Next on my list: figure out the difference between which causes this.

@scottnonnenberg

This comment has been minimized.

Show comment
Hide comment
@scottnonnenberg

scottnonnenberg Sep 21, 2017

It turns out that the hang is intermittent in the small repository, where it's 100% likely in our full Signal Desktop repository.

Anyway, I've made some changes to the repro repository to help make it more likely. You can go uncomment some things in blank.html to make it load a bunch of browser javascript. https://github.com/scottnonnenberg/electron-hang-repro

In the full repository, as far as I can tell it's the sheer amount of javascript files loaded and parsed which causes this to be 100% reproducible.

scottnonnenberg commented Sep 21, 2017

It turns out that the hang is intermittent in the small repository, where it's 100% likely in our full Signal Desktop repository.

Anyway, I've made some changes to the repro repository to help make it more likely. You can go uncomment some things in blank.html to make it load a bunch of browser javascript. https://github.com/scottnonnenberg/electron-hang-repro

In the full repository, as far as I can tell it's the sheer amount of javascript files loaded and parsed which causes this to be 100% reproducible.

@refractalize

This comment has been minimized.

Show comment
Hide comment
@refractalize

refractalize Apr 4, 2018

  • Electron version: 1.8.2, 1.8.4
  • Operating system: Ubuntu 14.04.1

I'm seeing this too, only we're not making two identical requests, just one is enough to trigger it. We're making a HTTPS call, POST or GET, no matter the endpoint. It fails to make the HTTP request (no outbound request seen in a HTTP proxy), as though the req.end() is not being called - so no timeouts are fired. I can confirm @scottnonnenberg's fix works.

Was able to reproduce the bug in both the renderer process and the main process.

Was not able to reproduce the bug in the equivalent versions of node, nor was I able to reproduce on Mac OSX, or Linux Fedora.

refractalize commented Apr 4, 2018

  • Electron version: 1.8.2, 1.8.4
  • Operating system: Ubuntu 14.04.1

I'm seeing this too, only we're not making two identical requests, just one is enough to trigger it. We're making a HTTPS call, POST or GET, no matter the endpoint. It fails to make the HTTP request (no outbound request seen in a HTTP proxy), as though the req.end() is not being called - so no timeouts are fired. I can confirm @scottnonnenberg's fix works.

Was able to reproduce the bug in both the renderer process and the main process.

Was not able to reproduce the bug in the equivalent versions of node, nor was I able to reproduce on Mac OSX, or Linux Fedora.

@mcferden

This comment has been minimized.

Show comment
Hide comment
@mcferden

mcferden May 14, 2018

  • Electron version: 1.8.4, 2.0.0
  • Operating system: Ubuntu 17.10, Ubuntu 18.04

I have this issue too. Here is an example repository. The series of requests hangs after the first request completes. On my machine it reproduces every time I run the app.

By trial and error I found out the relation with DNS lookup. If I use IP address in request URL, requests complete normally, and when I use domain name requests hang before leaving my machine (according to tcpdump).

This issue does not appear in pure Node.js and it is Linux specific, on Windows the app works fine.

mcferden commented May 14, 2018

  • Electron version: 1.8.4, 2.0.0
  • Operating system: Ubuntu 17.10, Ubuntu 18.04

I have this issue too. Here is an example repository. The series of requests hangs after the first request completes. On my machine it reproduces every time I run the app.

By trial and error I found out the relation with DNS lookup. If I use IP address in request URL, requests complete normally, and when I use domain name requests hang before leaving my machine (according to tcpdump).

This issue does not appear in pure Node.js and it is Linux specific, on Windows the app works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment