From my Ruby script I am spawning a PhantomJS process. That process will return a JSON string to Ruby, and Ruby will parse it.
Everything works fine, but when the PhantomJS script returns a huge JSON (more than 10000 entries), it seems that the Ruby doesn't know how to handle it (it doesn't get the whole string, but it gets cut).
An entry in the JSON looks like this (but some entries can have about 5 more attributes):
{"id" : 3, "nSteps" : 5, "class" : "class-name", "width" : 300, "height" : 500, "source" : "this is a big string", "nMove" : 10, "id-name" : "this is a big string", "checked" : true, "visible" : false}
This is the code I have right now:
@pid = Process.spawn("phantomjs",
"myparser.js",
:out => pipe_cmd_out, :err => pipe_cmd_out
)
Timeout.timeout(400) do
Process.wait(@pid)
pipe_cmd_out.close
output = pipe_cmd_in.read
return JSON.parse(output)
end
Is there any way I can read the JSON by chunks or somehow increase the buffer limit of the pipe?
EDIT:
In order to send the data from PhantomJS to Ruby, I have the following at the very end of my PhantomJS script:
console.log(JSON.stringify(data));
phantom.exit();
If I launch the PhantomJS script from the terminal I get the JSON correctly. However, when I do it from within Ruby, the response get cut.
The size of the string that is being put in the console.log
when it breaks is: 132648
EDIT:
I think I found out what is the exact problem. When I specify an :out when spawning the process, if the JSON returned is big (132648 length) it won't let the Ruby to read it. So when doing:
reader, writer = IO.pipe
pid = Process.spawn("phantomjs",
"script.js",
:out => writer
)
Timeout.timeout(100) do
Process.wait(pid)
writer.close
output = reader.read
json_output = JSON.parse(output)
end
It won't work.
But if I let PhantomJS to just write to its standard stdout, it will output the JSON correctly. So, doing:
reader, writer = IO.pipe
pid = Process.spawn("phantomjs",
"script.js"
)
Timeout.timeout(100) do
Process.wait(pid)
writer.close
output = reader.read
json_output = JSON.parse(output)
end
Will output the results in the terminal correctly. So I believe the problem is that somehow for big JSON it doesn't write correctly, or the Ruby reader doesn't know how to read it.