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

io.to_inputstrea.read(buf) shall read partially #3114

Open
yamam opened this issue Jul 7, 2015 · 3 comments
Open

io.to_inputstrea.read(buf) shall read partially #3114

yamam opened this issue Jul 7, 2015 · 3 comments

Comments

@yamam
Copy link

yamam commented Jul 7, 2015

test.c

#include <stdio.h>
#include <unistd.h>
int main(void)
{
    printf("123456789\n");
    fflush(stdout);
    sleep(10);
    return 0;
}

test.rb

use_open3 = JRUBY_VERSION.start_with?('9.0.0.0')

require 'open3' if use_open3

_, out = (use_open3 ? Open3 : IO).popen3('./a.out')
buf = Array.new(1024).to_java(:byte)
out.to_inputstream.read(buf)
puts buf

Compile to a.out.

$ gcc test.c

jruby-1.7.20.1

$ jruby test.rb
123456789

jruby-9.0.0.0.rc1

$jruby test.rb
<after 10 seconds>
123456789

InputStream#read(byte[] b) should read partially. But In jruby 9k, to_inputstrea.read blocks until a buffer completely filled.

@enebo enebo added this to the JRuby 9.0.0.0.rc2 milestone Jul 8, 2015
@enebo
Copy link
Member

enebo commented Jul 8, 2015

We might miss this for rc2 but I can confirm this has not been fixed since rc1.

@enebo enebo modified the milestones: JRuby 9.0.0.0.rc2, JRuby 9.0.0.0 Jul 9, 2015
@headius
Copy link
Member

headius commented Jul 9, 2015

If I modify your script to just read from the IO objects popen3 returns, MRI also blocks until 10 seconds have elapsed.

[] ~/projects/jruby $ time rvm ruby-2.2 do ruby test.rb
"123456789\n"

real    0m10.509s
user    0m0.300s
sys 0m0.242s

Based on that, it seems like this is not necessarily something we're doing wrong. A read against the InputStream you acquire will attempt to read to 1024 bytes or EOF. Since the process is still running, there's no EOF, so it blocks waiting for more data.

JRuby 1.7 blocks until process end with normal IO read, but returns quickly for the InputStream read, so there is a behavior change here. However the behavior change may be more correct.

I'm open to input here. JRuby 9k's InputStream here is just doing a call to IO read.

@yamam
Copy link
Author

yamam commented Jul 9, 2015

According to the Java API document, I think InputStream#read blocks until one byte read, but doesn't block until buffer filled.

https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html#read-byte:A-

This method blocks until input data is available, end of file is detected, or an exception is thrown.
there is an attempt to read at least one byte. 

Ruby IO has readpartial. So you can read partially. But InputStream doesn't have such a method. So you can't read partially from InputStream.

I want to process some part of my application in Java code for performance reason.
And I need to read partially from InputStream.

@enebo enebo modified the milestone: JRuby 9.0.0.0 Jul 14, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants