diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index b4c944dd..5afcce8e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2017-09-13 09:10:02 +0200 using RuboCop version 0.35.0. +# on 2017-09-18 13:40:11 -0400 using RuboCop version 0.35.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -33,7 +33,7 @@ Metrics/ClassLength: Metrics/CyclomaticComplexity: Max: 9 -# Offense count: 615 +# Offense count: 616 # Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: Max: 266 diff --git a/CHANGELOG.md b/CHANGELOG.md index aec20f71..2a0e8ac7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * [#163](https://github.com/slack-ruby/slack-ruby-client/pull/164): Use `OpenSSL::X509::DEFAULT_CERT_DIR` and `OpenSSL::X509::DEFAULT_CERT_FILE` for default ca_cert and ca_file - [@leifcr](https://github.com/leifcr). * [#161](https://github.com/slack-ruby/slack-ruby-client/pull/161): Added support for cursor pagination - [@dblock](https://github.com/dblock). +* [#162](https://github.com/slack-ruby/slack-ruby-client/pull/162): Gracefully close websocket on `Errno::EPIPE` - [@johanoskarsson](https://github.com/johanoskarsson). * Your contribution here. ### 0.9.1 (8/24/2017) diff --git a/lib/slack/real_time/concurrency/celluloid.rb b/lib/slack/real_time/concurrency/celluloid.rb index d5ddb57c..9a277e48 100644 --- a/lib/slack/real_time/concurrency/celluloid.rb +++ b/lib/slack/real_time/concurrency/celluloid.rb @@ -34,7 +34,7 @@ def run_loop @connected = @socket.connect driver.start loop { read } if socket - rescue EOFError => e + rescue EOFError, Errno::EPIPE => e logger.debug("#{self.class}##{__method__}") { e } driver.emit(:close, WebSocket::Driver::CloseEvent.new(1001, 'server closed connection')) unless @closing ensure diff --git a/spec/slack/real_time/concurrency/celluloid_spec.rb b/spec/slack/real_time/concurrency/celluloid_spec.rb index 51d7aa56..35443cf0 100644 --- a/spec/slack/real_time/concurrency/celluloid_spec.rb +++ b/spec/slack/real_time/concurrency/celluloid_spec.rb @@ -7,45 +7,55 @@ context 'with url' do let(:url) { 'wss://echo.websocket.org/websocket/xyz' } let(:logger) { ::Logger.new(STDOUT) } - let(:test_socket) do - Class.new(described_class) do - def read - fail EOFError + + [EOFError, Errno::EPIPE].each do |err| + context "finishing run_loop with #{err}" do + let(:test_socket) do + Class.new(described_class) do + def read + fail options[:err] + end + end end - end - end - let(:socket) { test_socket.new(url, ping: 42, logger: logger) } - let(:driver) { WebSocket::Driver::Client } - let(:ws) { double(driver) } - subject { socket } - - describe '#connect!' do - pending 'connects' - pending 'pings every 30s' - end - context 'with a driver' do - before do - socket.instance_variable_set('@driver', ws) - end + let(:socket) do + test_socket.new(url, ping: 42, logger: logger, err: err) + end - describe '#disconnect!' do - it 'closes and nils the websocket' do - expect(ws).to receive(:close) - socket.disconnect! + let(:driver) { WebSocket::Driver::Client } + let(:ws) { double(driver) } + subject { socket } + + describe '#connect!' do + pending 'connects' + pending 'pings every 30s' end - end - describe '#run_loop' do - it 'runs' do - expect(ws).to receive(:emit) - expect(ws).to receive(:start) - socket.run_loop + context 'with a driver' do + before do + socket.instance_variable_set('@driver', ws) + end + + describe '#disconnect!' do + it 'closes and nils the websocket' do + expect(ws).to receive(:close) + socket.disconnect! + end + end + + context 'consumes data' do + it 'runs' do + expect(ws).to receive(:emit) + expect(ws).to receive(:start) + expect(logger).to receive(:debug).with("#{test_socket}#run_loop") + socket.run_loop + end + end end + + pending 'send_data' end end - - pending 'send_data' end end rescue LoadError