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

Update pdf2svg.js #8461

Closed
wants to merge 4 commits into from
Closed

Conversation

yshahin
Copy link

@yshahin yshahin commented May 30, 2017

Changing file write to sync solves the problem.
Looks like promise chaining with a file write at the end with out waiting for the write to happen causes the issue.

Fixes #8419

Changing file write to sync solves the problem.
Looks like promise chaining with a file write at the end with out waiting for the write to happen causes the issue.
@yurydelendik
Copy link
Contributor

I wonder if there is a logical explanation to this fix -- node.js people recommend to use async callbacks.

Looks like promise chaining with a file

callback chaining

});
}
});
if(!fs.existsSync('./svgdump/')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a space after if, so that it becomes if (!fs.....

}
});
if(!fs.existsSync('./svgdump/')) {
fs.mkdirSync('./svgdump/')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need a semicolon at the end of the line.

if(!fs.existsSync('./svgdump/')) {
fs.mkdirSync('./svgdump/')
}
fs.writeFileSync('./svgdump/' + name + "-" + pageNum + '.svg', svgdump, 'utf-8');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the double quotes to single quotes on this line. Moreover, the prints are now gone. Is there a way to add them back?

@timvandermeij
Copy link
Contributor

I'm also wondering about the explanation for this. I'm fine with the sync approach if that works, but I do not understand why the async approach does not work properly.

@yshahin
Copy link
Author

yshahin commented May 31, 2017

I think the problem is not with the async calls but probably with when the call gets executed.
The "End Document" print statement gets printed before the write happens, which I think might be the cause.
By blocking the promise till the write happens this solves the problem.
There might be a way to do it with async calls but I did not figure it out yet.

Will continue working on it.

FYI:
also found these

  1. Memory leaks in loops with Promise nodejs/node#6673
  2. Long chain promise => Out of memory petkaantonov/bluebird#1068

yshahin and others added 3 commits May 31, 2017 18:17
@yshahin
Copy link
Author

yshahin commented May 31, 2017

I tried different different things but only the sync file write works. I think we need to consult a node export here to tell us what the issue is. From the previous link it seems like a memory leak problem.

@yurydelendik
Copy link
Contributor

yurydelendik commented May 31, 2017

By blocking the promise till the write happens this solves the problem.

I tried adding callback to block a promise -- the same problem.

I tried different different things but only the sync file write works.

I'm worry it's just coincidence and the patch is just masking the real problem, which can surface later.

@yurydelendik
Copy link
Contributor

Blocked by nodejs/node#13337

@yurydelendik
Copy link
Contributor

node.js experts say it is a memory leak, so switching to sync might only fix the issue only for this case and can reappear in the future. I recommend to wait until leak will be found.

@yshahin
Copy link
Author

yshahin commented May 31, 2017

@yurydelendik take a look at this petkaantonov/bluebird#1068 it seems like an inherit problem in promises in node.
The solution presented requires bluebird lib, I can try it out and see if it works.

@yurydelendik
Copy link
Contributor

@yshahin okay, pdf.js also have polyfill in compatibility.js, see if "forcing" it will help

@yurydelendik
Copy link
Contributor

@yashsriv the yurydelendik/nodesegfault@2bb6f26 fixes the issue, so you are right it's due to Promises implementation.

@yurydelendik
Copy link
Contributor

Blocked by nodejs/help#652

@yshahin
Copy link
Author

yshahin commented Jun 1, 2017

@yurydelendik how do you want to handle this?
Use the your fix? or change it to sync calls?

@timvandermeij
Copy link
Contributor

If it works with our promise polyfill and not with the native Node.js one, I'm not sure why the Node.js people claim the memory leak is on our side. Even if there is a memory leak, it shouldn't matter if you use sync/async writing.

Personally I'm fine with the sync approach here to solve this issue, but I'll let @yurydelendik make the call.

@Rob--W
Copy link
Member

Rob--W commented Jun 18, 2017

I'm closing this PR in favor of mine at #8540, because moving from async to sync is unnecessary.

The reason that moving from async to sync "solves" the problem is that it forces Node.js to suspend execution until the file writing finishes. Consequently, pages are effectively processed sequentially.
My patch also changes the pdf2svg code to process the pages sequentially, but without blocking execution.

In this thread, it has been said that using our Promise polyfill solves the issue as well. I think that this is a mere coincidence. Normally promises are scheduled as a microtask, but with our polyfill it is scheduled using setTimeout, which causes the promise to resolve less quickly. Consequently, when the SVG generation process (with many "promises") finishes, some file writing requests have likely finished as well, allowing Node.js to reclaim the memory for the string that is passed to fs.writeFile (in pdf2svg.js).

@Rob--W Rob--W closed this Jun 18, 2017
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

Successfully merging this pull request may close these issues.

5 participants