Skip to content

Commit

Permalink
Do not silently discard undelivered messages
Browse files Browse the repository at this point in the history
The plugin no longer discards messages which it fails to send if the server disconnects and sends some content prior to the disconnection.

Example situation before the fix:

1. A connection is established between a server and the plugin.
2. The plugin delivers some messages to the server.
  2.1) It may or may not read something that it received from the server.
  2.2) It sends the payload to the server.
3. The server sends some content back and disconnects.
4. The plugin tries to deliver some other messages to the server.
  4.1) It tries to read (if r.any?) and expects to get an EOFError in case the server just died.
  4.2) No error is thrown as some content just arrived from the server. It is discarded.
  4.3) The first payload is written to the socket, no error being thrown.
  4.4) The next payload finally fails with EOFError upon reading from the socket and an retry follows.

This commit fixes the 4.1 and 4.2 phases. The reading is now performed repeatedly while there's still something to read left so that we don't miss the EOFError exception.
  • Loading branch information
jsmucr authored Nov 28, 2017
1 parent e1bea77 commit 831f2b9
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions lib/logstash/outputs/tcp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,14 @@ def register
begin
client_socket = connect unless client_socket
r,w,e = IO.select([client_socket], [client_socket], [client_socket], nil)
# don't expect any reads, but a readable socket might
# mean the remote end closed, so read it and throw it away.
# we'll get an EOFError if it happens.
client_socket.sysread(16384) if r.any?
loop do
break if !r.any?
# don't expect any reads, but a readable socket might
# mean the remote end closed, so read it and throw it away.
# we'll get an EOFError if it happens.
client_socket.sysread(16384)
r = IO.select([client_socket])
end

# Now send the payload
client_socket.syswrite(payload) if w.any?
Expand Down

0 comments on commit 831f2b9

Please sign in to comment.