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

Large nw.js apps sometimes don't load on mac and linux #3307

Closed
JustASquid opened this issue Mar 28, 2015 · 40 comments
Closed

Large nw.js apps sometimes don't load on mac and linux #3307

JustASquid opened this issue Mar 28, 2015 · 40 comments
Assignees

Comments

@JustASquid
Copy link

Hi!

I'm working on a fairly large-scale game using nw.js (In the Construct 2 engine) and it's having some problems on non-Windows platforms.

My users have recently reported that with the newer versions of nw.js, the app will often fail to load on mac and linux devices. The same app runs fine on windows, and on mac in the browser (I haven't done Linux browser testing).

For some users, the failure to load happens consistently, however for some (and in my personal testing) it only happens some of the time. The failure also happens right at the start of the app.

Here's what the error console looks like on mac:
screen shot 2015-03-28 at 10 31 16 am

Here's an export to test for yourself. I've stripped out all the C2 code and layouts, leaving only the image files and object data.
https://dl.dropboxusercontent.com/u/41931267/NWTest_OSX32.zip

Here's the HTML5 export which works fine. Keep in mind it will take a while to load in browser as there's a lot of image files.
https://dl.dropboxusercontent.com/u/41931267/NWJS_issue/index.html

Here's the Construct 2 source:
https://dl.dropboxusercontent.com/u/41931267/NWJS_issue.capx

Please let me know if you have any questions.
Daniel

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@ghost
Copy link

ghost commented Mar 31, 2015

ERR_INSUFFICIENT_RESOURCES..."a lot of image files"...
Okay, I ran the test.
There's a TON of images that are being loaded, and they're probably going to stay loaded even when not in use.
And since there's so many images, it's using up a ton of memory.
Just a guess, though.
Unfortunately, this is a problem with Construct 2 loading too much.
Which can't be fixed without telling the Construct 2 developers to stop loading images in advance, and to unload images if they haven't been in use for a while.
So basically, there's nothing that can be done short of patching the output from Construct 2.
But the way it's laid out, you'd need to make a patcher program to do it, because every time the game is rebuilt it will need to be repatched, and as resources are added the line numbers will change.
Also, remember that the patch has to remove resources that aren't in use, or everything will just fail once enough stuff has loaded(as in, when someone is at a certain point through the game)

@AshleyScirra
Copy link

Browsers lazy-load images. Construct 2 simply points the src attribute of Image objects to their paths, and does not use them. Browsers then lazy-load them the first time they are used. So it should not actually be loading much on startup. If it works in Chrome but not in NW.js, then it suggests perhaps NW.js has broken this lazy loading scheme or otherwise broken the ability to load multiple images.

BTW this demo uses ~450 images which isn't actually a whole lot considering it's already spritesheeting an even greater number of images. We've seen real games using thousands of images.

@morgondag
Copy link

Finding this to be a problem as well. ( not using construct2).
Isen't there a chrome-arg for increasing or disabling this limit for an offline app?

@OldFlak
Copy link

OldFlak commented May 5, 2015

Yes, please address this issue, thanks.

@Everade
Copy link

Everade commented May 5, 2015

Would be great if you guys could take some of your time and look into this matter.
Having the same issue as well.

@rogerwang
Copy link
Member

Will look to fix this. Could anyone please provide the case?

@JustASquid
Copy link
Author

Thanks Roger!

What do you mean by 'provide the case' though? Anything you need from me here?

@rogerwang
Copy link
Member

@JustASquid a sample application to reproduce the issue.

@JustASquid
Copy link
Author

@rogerwang is the attached zip file with exported nw project for osx insufficient?

@rogerwang rogerwang self-assigned this May 19, 2015
@DanielJoyce
Copy link

You should be packaging your images into fewer larger images, and then using chunks of those images. Probably running out of graphic handles.

You need to use a sprite sheet.

http://firefoxosgaming.blogspot.com/2014/10/tile-maps-in-construct-2.html

This will improve memory pressure, resource handle usage, and load times.

@JustASquid
Copy link
Author

@DanielJoyce

I do use sprite sheets! even so, there are a lot of them because C2 spritesheets on a per-animation basis.

Anyway that point is moot since it works perfectly fine in Chrome as well as older NW versions.

@rogerwang has there been any progress on this? It's a pretty big deal for me.

@baconbrad
Copy link

@JustASquid As a workaround have you tried not packaging the images in your NW.js project and just have them called from a folder in the same directory as your NW.js binary?

@JustASquid
Copy link
Author

@baconface images are not packaged for mac export anyway, they are stored unpackaged in a subdirectory. not sure about linux, but they have the same problem so that probably won't fix it, unless I'm misunderstanding you.

@ghostoy
Copy link
Member

ghostoy commented Jun 3, 2015

Could you try to pass --file-descriptor-limit=8192 via command line ?

@RIAEvangelist
Copy link

does --file-descriptor-limit=8192 fix the issue?

@JustASquid
Copy link
Author

@RIAEvangelist @ghostoy I'm already using --file-descriptor-limit<10000> - is there some significance to the number 8192? also I noticed the syntax is slightly different.

@morgondag
Copy link

if you run ulimit -a in terminal you can see your current file-description limit.
default on mac seams to be 256?
going to test increasing the limit.
This would be neat if we could call this from package.json run arguments

@RIAEvangelist
Copy link

@JustASquid not sure, but there was a week since it was suggested as a solution, and was wondering the outcome. Perhaps the formatting may make a difference.

@morgondag looking forward to seeing your results.

@ghostoy
Copy link
Member

ghostoy commented Jun 12, 2015

@JustASquid Please run ulimit -a -H to show your hard limit on file descriptor. If there is a hard limit, you can't exceed it normally. Then you have to set your hard limit and restart your laptop.
The syntax you are using is wrong and please try --file-descriptor-limit=10000.

@JustASquid
Copy link
Author

@ghostoy @morgondag @RIAEvangelist Thanks for your help!

I've managed to change ulimit -n by the command line. (Not called file descriptor limit, but called 'open files'.) It was indeed 256 by default.

Doing this manually made the test app run fine. I changed the argument in package.json from '--file-descriptor-limit<10000>' to '--file-descriptor-limit=10000' but it didn't seem to work.

Anyway, I don't want to have to ask my users to manually play around with system config like this. Is there any way to have the app change the file limit?

also, more screwing around has meant that the hard limit has been set to 256 - anyone know how to fix that? I tried sudo launchctl limit maxfiles 4096 8192 but that had no effect.

My mac is running OSX Yosemite v 10.10.3.

@morgondag
Copy link

@RIAEvangelist So it actually seams to fix my launch issues.
Keep in mind I have my .app on steam so adding the launch argument
--file-descriptor-limit=10000
Ad then running the application thought steam now starts as expected.
How ever there might be some cache going on.

ulimit -a

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 709
virtual memory          (kbytes, -v) unlimited

ulimit -a -H

core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) unlimited
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 65532
cpu time (seconds, -t) unlimited
max user processes (-u) 1064
virtual memory (kbytes, -v) unlimited

I have a rather old macbook air I'm testing on.
If anyone want to give it a try send me an email and i can hit you up
with a cdkey for steam:
kim@morgondag.nu

@RIAEvangelist
Copy link

@JustASquid you could try something like node-cmd?

npm install node-cmd

var cmd=require('node-cmd');

cmd.run('ulimit blah blah');

if it's cross platform you will have to handle the various OS commands. Should be simple though.

@morgondag sweet write up! would help if I had a mac.

@JustASquid
Copy link
Author

@ghostoy @morgondag @RIAEvangelist

My post seemed to post weirdly out of order, just replying again because there are still some unanswered questions. Mainly, what's a good way to do this without screwing with the user's computer, or requiring the user to screw with their computer? For linux people it wouldn't be a huge hassle but mac users aren't always going to be tech savvy.

@ghostoy
Copy link
Member

ghostoy commented Jun 14, 2015

@JustASquid --file-descriptor-limit has to be passed as command line argument. It DOSN'T work for chromium-args in package.json. That means you need to start nw with nw --file-descriptor-limit=10000 path/to/your/app.
limit -n reports the soft limit and it can be fixed by passing --file-descriptor-limit correctly. But for hard limit shown by limit -n -H, you can't work it out except reset it by root user. Fortunately in your case, it's "unlimited" as usually do.

@ghostoy
Copy link
Member

ghostoy commented Jun 14, 2015

@JustASquid Please refer to this link for setting hard limit on Linux and Mac.

@JustASquid
Copy link
Author

@ghostoy OK, thanks!

I managed to get it working consistently by opening the app with the command line and using --file-descriptor-limit=10000.

I'm using construct 2 which exports the application as a .app file.
What's a good way to have the app set this launch option automatically? I looked it up but the most common solution involved running Automator to wrap the app in another app or some weird stuff like that. Is there a simple way? Even better, is there a way to do it that would let me apply the change on my Windows machine? Currently my workflow to publish the game doesn't require using a mac at all and I'd like to avoid that if possible.

Thanks so much for your help!
Daniel

EDIT: Actually, apparently it's still occasionally hanging on load even when passing that argument. looking into it more now...

@JustASquid
Copy link
Author

Yeah, it's still hanging on load sometimes, giving the same errors.

this is with ulimit -n definitely being 8192 and also passing --file-descriptor-limit by the command line as a launch option.

Soo... it looks like the issue might be elsewhere?

@DanielJoyce
Copy link

Do you REALLY need 8000 open file descriptors? Are you remembering to close
them after loading assets? I suspect you are leaking file descriptors.

On Sun, Jun 14, 2015, 00:20 JustASquid notifications@github.com wrote:

Yeah, it's still hanging on load sometimes, giving the same errors.

this is with ulimit definitely being 8192 and also passing
--file-descriptor-limit by the command line as a launch option.

Soo... it looks like the issue might be elsewhere?


Reply to this email directly or view it on GitHub
#3307 (comment).

Daniel Joyce

The meek shall inherit the Earth, for the brave will be among the stars.

@JustASquid
Copy link
Author

@DanielJoyce

No, I don't need 8000 but I need more than 256. I'd guess I have about 500 or so images. I have no idea how it works under the hood but i guess it's trying to 'open' all those files at once?

I still haven't seen anyone explain why it works in Chrome but not nw.

@morgondag
Copy link

going to run some more test on my .app i have seams like some of you still get hangups?
So the case with all the files on these types of applications is that they usually load sprites of images beforehand so they are always available in the application. ( often canvas/webgl). See any JS bases game-engine (phaser/impact/Contruct).

So changing the applications and engines is not a solution to the problem.
it works in chrome but not in NW.

is there a different file limit set for nw? Why?

@RIAEvangelist
Copy link

One thing I have done for some image software I built is to load the images as base64.

It has fixed the issues I was having and I am opening like 200 remote images. I assume this would work with normal images as well.

since mine are remote I loaded via XHR then converted to b64 but you could easily do the same thing pre DOM render with node, generate a style sheet with your images embedded on the fly so you don't have to update anything when you modify the images. and inject it into the DOM.

@JustASquid
Copy link
Author

Any progress/ideas anyone?

@ghostoy
Copy link
Member

ghostoy commented Jun 27, 2015

@JustASquid Could you upload a sample to reproduce the issue?

@JustASquid
Copy link
Author

@ghostoy The export is provided in the original post - were you after something else?

@ghostoy
Copy link
Member

ghostoy commented Jun 27, 2015

@JustASquid Sorry. Forget that.

@ricardobeat
Copy link

Browsers have a max number of connections per hostname (http://www.browserscope.org/?category=network), and that will naturally cause the image loading to be staggered. This limit doesn't seem to apply to local resources. @JustASquid you could try serving the images via http/localhost from the node side; it sounds backwards but might resolve the issue.

@JustASquid
Copy link
Author

@ricardobeat

I don't have very much knowledge in this area, but does this explain why it will work in Chrome but not nw?

Basically since I'm using an engine I'm pretty much locked out from making changes to stuff like the image loading. The engine developers are convinced it's a nw.js bug so I really need to know if this is something that nw can fix or if it's something that needs an engine workaround.

@ricardobeat
Copy link

@JustASquid I don't know the internals of nw, so this is just a wild guess. You should be able to change the image URLs to use http://localhost instead of relative paths, without touching the engine code. A quicker way to test this would be to just serve everything from a static http server (see #2901).

@JustASquid
Copy link
Author

I'd like to bump the issue - while ricardo's solution may work, I don't have the internal know-how and/or engine access to implement a workaround as suggested.

It's been over three months and I'm getting very close to the planned release date of my game. I'm very worried at the moment that I'm not going to be able to make launch.

@rogerwang is there anything we can do?

@nwjs-bot
Copy link

This should be working with latest version now.

In 0.13 we changed to an optimized architecture so more features can be supported, see http://nwjs.io/blog/whats-new-in-0.13/ and it's good for keeping up with Chromium upstream -- we released with Node.js v6.0 and new Chromium versions within 1 day after upstream release.

The new version would fixed many issues reported here and we're scrubbing them. This issue is closed as we believe it should be fixed. Please leave a message if it isn't and we'll reopen it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests