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

Pipeline shutdown can be blocked by stdin input #1769

Closed
jordansissel opened this issue Sep 23, 2014 · 16 comments
Closed

Pipeline shutdown can be blocked by stdin input #1769

jordansissel opened this issue Sep 23, 2014 · 16 comments

Comments

@jordansissel
Copy link
Contributor

For whatever reason, I can't figure out how to close stdin in JRuby and interrupt any currently-blocked reads on stdin.

This confuses users and is generally annoying.

The symptom is that ^C should terminate logstash cleanly, but stdin never really stops so the pipeline stays up until you close stdin as a user (via ^D)

(related: #1767)

@jordansissel
Copy link
Contributor Author

From another thread, I have attempted:

  • java.lang.System.in.close()
  • $stdin.close
  • Thread#raise
  • IO::select([$stdin], ...)

None are effective. Closing doesn't interrupt any active reads. IO::select always says $stdin is ready to read even when there is no data.

@jordansissel
Copy link
Contributor Author

Contrast to MRI 2.1.2:

  • $stdin.sysread(1) - gets a RuntimeError: "`sysread': unhandled exception"
  • IO.select([$stdin], nil, nil, nil) - gets same error as above, except it says `select'.

@colinsurprenant colinsurprenant added this to the v1.5.0 milestone Sep 23, 2014
@colinsurprenant colinsurprenant self-assigned this Sep 23, 2014
@jordansissel
Copy link
Contributor Author

rvm default do ruby -e 't = Thread.new { begin ; p :sysread => $stdin.sysread(1); puts "Done"; rescue => e; p :e => e; raise; end }; sleep 3; puts "Closing $stdin"; $stdin.close; puts "Interrupting "; t.raise; t.join'

@talevy
Copy link
Contributor

talevy commented Nov 11, 2014

looks related: http://jira.codehaus.org/browse/JRUBY-5723

@suyograo suyograo modified the milestones: 2.0, v1.5.0 Nov 11, 2014
@colinsurprenant
Copy link
Contributor

Just a few notes, as I looked at this a bit last evening.

  • stdin but stdio in general is not selectable in Java NIO. (Not sure if it is in NIO2). Doing IO.select([$stdin], nil, nil, 0) in JRuby will not work as intended.
  • blocking read on stdin in a thread in Java NIO is non-interruptible, period. ❗

The only options I see for this are

  • if NIO2 support selectable stdio we could implement this using NIO2, but only for Java 7+
  • implement our own stdin reader either by just wrapping needed POSIX system calls with FFI and maybe injecting a little C for better performance.

@jordansissel
Copy link
Contributor Author

(reposting from hipchat)
+1 on FFI because it will work on both MRI and JRuby.

@seanfahey
Copy link

Is it possible to have the Getting Started documentation updated, until the issue is fixed? http://logstash.net/docs/1.4.2/tutorials/getting-started-with-logstash in the "Logstash in two commands" section.

@josegonzalez
Copy link

EDIT: Seems my issue is actually #1779. Sorry!

Note: I'm unable to get it to close, even with CTRL+D. I have to manually kill the agent using kill -term or kill -9. I'm running under the openjre in case that helps.

Also, here is the config i'm running with, which doesn't use stdio as far as I can tell:

/opt/logstash/bin/logstash -e 'input { redis { key => "metricsd" data_type => "list" } } output { elasticsearch { host => localhost } stdout { codec => "json" } }'

When I had it running under stdin instead of redis, I was able to kill the agent, though it did take a while for it to die.

I can also provide a Vagrantfile where this issue is reproducible (at least for me) if that helps.

@colinsurprenant
Copy link
Contributor

@josegonzalez for the shutdown + redis issue see #2871

@colinsurprenant
Copy link
Contributor

just a quick update to say I found a way to extract an InterruptibleChannel from System.in - I'll be making a test integration in the stdin input plugin which should allow a simple ^C to correctly shutdown logstash when using stdin input.

I looks like this solution only works on Java 8 though.

@jordansissel
Copy link
Contributor Author

@colinsurprenant I'm OK with this - Java 7 is EOL anyway, so I think it's reasonable to expect that Java 8 should become more common very soon.

@jordansissel
Copy link
Contributor Author

<3 you so much for finding this solution

@josegonzalez
Copy link

Yay java 8! Good work @colinsurprenant :)

@colinsurprenant
Copy link
Contributor

landed the jruby-stdin-channel gem for it. just need to insert that into the stdin input and see how that behave :P

@colinsurprenant
Copy link
Contributor

inserted in the stdin input in logstash-plugins/logstash-input-stdin#3

@suyograo suyograo removed this from the v2.0.0 milestone Jun 18, 2015
@jsvd
Copy link
Member

jsvd commented Mar 11, 2016

please follow this in logstash-plugins/logstash-input-stdin#3

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

7 participants