waithook 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5df3978af4bd4dc3330d86dd3a1948d082d1642882163066ec4e09d9b63245b2
4
- data.tar.gz: af869d9efc1604f24b3fd1455767f06d5af75d62c5a225611b87b450e21f4bc1
3
+ metadata.gz: b1f0cc2d5d5ec7b85af2b2d46e1fb0d027e44f59280383144852cd977ef7476e
4
+ data.tar.gz: 3b91c47c92011bb8ffdf2d6178f4e3b6634a276e3bea95038f81938f787f1a5c
5
5
  SHA512:
6
- metadata.gz: f2aa1c1079788668a57c3483708aa5158f3fb2b9abdfa8fafb227027ed83c085d970b97d65068a34373cfcb5edcae0ffc481351b1ebc53ee726f7f707eaaadec
7
- data.tar.gz: 19c9797a9712c5df295515da8a5b299132ec2176364094d7b6d5f7ca96e502aa986e379a6be94fad05c5109114bc7b7423c9ce6550bf2e1d7d903b5209c7d5a5
6
+ metadata.gz: dd53a11900c20386e09d9eaf95f59e8ff787063844367d3d49b2bd374b760c1ab967e022d8d195e10d79c2e44381b1fbc7dbdf34417d49ca93b7cd8e6b74f542
7
+ data.tar.gz: 17249a6bdddb4e9d24a441ceb68273f81649f8a1cf00514bc51464cb284f5291ba1d4030b53542981ebb702e29bb2d2ffbd4f9fbc3300506758441e658cbd4ba
data/Gemfile CHANGED
@@ -4,5 +4,6 @@ gem 'rake'
4
4
  gem 'minitest-reporters'
5
5
  gem 'excon'
6
6
  gem 'addressable'
7
+ gem 'coderay'
7
8
 
8
9
  gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- waithook (0.4.0)
4
+ waithook (0.4.2)
5
5
  websocket (~> 1.2)
6
6
 
7
7
  GEM
@@ -11,6 +11,7 @@ GEM
11
11
  public_suffix (>= 2.0.2, < 7.0)
12
12
  ansi (1.5.0)
13
13
  builder (3.3.0)
14
+ coderay (1.1.3)
14
15
  excon (0.112.0)
15
16
  minitest (5.25.1)
16
17
  minitest-reporters (1.7.1)
@@ -28,6 +29,7 @@ PLATFORMS
28
29
 
29
30
  DEPENDENCIES
30
31
  addressable
32
+ coderay
31
33
  excon
32
34
  minitest-reporters
33
35
  rake
data/example/example.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'looksee'
2
2
  require 'net/http'
3
3
 
4
- require './websocket-client'
4
+ require_relative '../lib/waithook/websocket_client'
5
5
 
6
6
  HOST = 'localhost'
7
7
  PORT = 3012
@@ -1,7 +1,7 @@
1
1
  require 'looksee'
2
2
  require 'excon'
3
3
 
4
- require './websocket-client'
4
+ require_relative '../lib/waithook/websocket_client'
5
5
 
6
6
  #HOST = 'localhost'
7
7
  #PORT = 3012
@@ -1,7 +1,7 @@
1
- require_relative './waithook'
1
+ require_relative '../lib/waithook'
2
2
  require 'excon'
3
3
 
4
- waithook = Waithook.subscribe('my-super-test', host: 'localhost', port: 3012)
4
+ waithook = Waithook.subscribe(path: 'my-super-test', host: 'localhost', port: 3012)
5
5
 
6
6
  Excon.post('http://localhost:3012/my-super-test', body: Time.now.to_s)
7
7
 
@@ -1,3 +1,3 @@
1
1
  class Waithook
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.3"
3
3
  end
@@ -79,7 +79,7 @@ class Waithook
79
79
  end
80
80
  end
81
81
 
82
- # Estabilish connection to server and send initial handshake
82
+ # Establish connection to server and send initial handshake
83
83
  def connect!
84
84
  logger.info "Connecting to #{@host} #{@port}"
85
85
 
@@ -118,7 +118,7 @@ class Waithook
118
118
  def _start_parser!
119
119
  @reader, @writter = IO.pipe
120
120
  @processing_thread = Thread.new do
121
- Thread.current.abort_on_exception = true
121
+ # Thread.current.abort_on_exception = true
122
122
  begin
123
123
  logger.debug "Start reading in thread"
124
124
  handshake_response = _wait_handshake_response
@@ -129,8 +129,14 @@ class Waithook
129
129
  _handshake_recieved!
130
130
  _wait_frames!
131
131
  rescue Object => error
132
+ # if got error - close socket and end thread
133
+ # @last_connection_error will be detected in #wait_message and raised to caller thread,
134
+ # so caller can decide to reconnect or do something else
135
+ @last_connection_error = error
136
+ close!(send_close: false, kill_processing_thread: false) rescue nil
137
+ @messages.close
138
+
132
139
  logger.error "#{error.class}: #{error.message}\n#{error.backtrace.join("\n")}"
133
- raise error
134
140
  end
135
141
  end
136
142
  end
@@ -150,7 +156,7 @@ class Waithook
150
156
  _send_frame(:text, payload)
151
157
  end
152
158
 
153
- # Wait for new message (thread safe, all waiting threads will recieve a message)
159
+ # Wait for new message (thread safe, all waiting threads will receive a message)
154
160
  # Message format [type, data], e.g. <tt>[:text, "hello world"]</tt>
155
161
  def wait_new_message
156
162
  waiter = Waiter.new
@@ -158,14 +164,27 @@ class Waithook
158
164
  waiter.wait
159
165
  end
160
166
 
161
- # Synchroniously waiting for new message. Not thread safe, only one thread will receive message
167
+ # Synchronously waiting for new message. Not thread safe, only one thread will receive message
162
168
  # Message format [type, data], e.g. <tt>[:text, "hello world"]</tt>
163
169
  def wait_message
164
- @messages.pop
170
+ begin
171
+ message = @messages.pop
172
+ if (!message || message.first == nil) && @messages.closed? && @last_connection_error
173
+ raise @last_connection_error
174
+ end
175
+
176
+ return message
177
+ rescue => error
178
+ if @last_connection_error
179
+ raise @last_connection_error
180
+ else
181
+ raise error
182
+ end
183
+ end
165
184
  end
166
185
 
167
186
  # Wait until server handshake recieved.
168
- # Once it's recieved - we can are listening for new messages
187
+ # Once it's received - we can are listening for new messages
169
188
  # and connection is ready for sending data
170
189
  def wait_handshake!
171
190
  return true if @handshake_received
@@ -240,16 +259,20 @@ class Waithook
240
259
  data.join("")
241
260
  end
242
261
 
262
+ def socket_open?
263
+ @socket && !@socket.closed?
264
+ end
265
+
243
266
  # Send <tt>:close</tt> message to socket and close socket connection
244
- def close!(options = {send_close: true})
267
+ def close!(send_close: true, kill_processing_thread: true)
245
268
  unless @is_open
246
269
  logger.info "Already closed"
247
270
  return false
248
271
  end
249
272
 
250
273
  logger.info "Disconnecting from #{@host} #{@port}"
251
- @processing_thread.kill
252
- _send_frame(:close) if options[:send_close]
274
+ @processing_thread.kill if kill_processing_thread
275
+ _send_frame(:close) if send_close
253
276
  @socket.close
254
277
  @is_open = false
255
278
 
data/lib/waithook.rb CHANGED
@@ -118,7 +118,11 @@ class Waithook
118
118
  client.ping_sender
119
119
  logger.debug("Exit ping sender thread")
120
120
  rescue => error
121
- logger.warn("Error in ping sender thread: #{error.message} (#{error.class})\n#{error.backtrace.join("\n")}")
121
+ if error.message == "closed stream" && !@client.socket_open?
122
+ logger.debug("Connection closed, stopping ping sender thread")
123
+ else
124
+ logger.warn("Error in ping sender thread: #{error.message} (#{error.class})\n#{error.backtrace.join("\n")}")
125
+ end
122
126
  end
123
127
  end
124
128
  end
@@ -146,7 +150,11 @@ class Waithook
146
150
  Timeout.timeout(timeout) do
147
151
  while true
148
152
  _, data = @client.wait_message
149
- webhook = Webhook.new(data, logger)
153
+ webhook = Webhook.new(
154
+ data,
155
+ logger: logger,
156
+ forward_options: (options[:forward_options] || {}).merge(@options[:forward_options] || {})
157
+ )
150
158
  if @filter && @filter.call(webhook) || !@filter
151
159
  @messages << webhook
152
160
  return webhook
@@ -180,7 +188,7 @@ class Waithook
180
188
  # Raw message from waithook server
181
189
  attr_reader :message
182
190
 
183
- def initialize(payload, logger = nil)
191
+ def initialize(payload, logger: nil, forward_options: {})
184
192
  @message = payload
185
193
  data = JSON.parse(@message)
186
194
  @url = data['url']
@@ -188,9 +196,17 @@ class Waithook
188
196
  @body = data['body']
189
197
  @method = data['method']
190
198
  @logger = logger
199
+ @forward_options = forward_options
191
200
  end
192
201
 
193
- def pretty_print
202
+ def pretty_print(pp_arg = nil, *args)
203
+ return super if pp_arg && defined?(super) # method from 'pp' library has same name
204
+
205
+ if !@body
206
+ @logger&.debug("Error: Waithook::Webhook has no @body")
207
+ return @message
208
+ end
209
+
194
210
  if @body.start_with?('{') && @body.end_with?('}') || @body.start_with?('[') && @body.end_with?(']')
195
211
  begin
196
212
  body_data = JSON.parse(body)
@@ -202,15 +218,15 @@ class Waithook
202
218
  require 'coderay'
203
219
  pretty_body = CodeRay.scan(pretty_body, :json).term
204
220
  rescue => error
205
- logger&.debug("Error while trying to use CodeRay: #{error.message}")
221
+ @logger&.debug("Error while trying to use CodeRay: #{error.message}")
206
222
  end
207
223
  return "#{JSON.pretty_generate(data_without_body)}\nBody:\n#{pretty_body}"
208
224
  rescue JSON::ParserError => error
209
- logger&.debug("Error while parsing json body: #{error.message}")
225
+ @logger&.debug("Error while parsing json body: #{error.message}")
210
226
  end
211
227
  end
212
228
 
213
- return message
229
+ return @message
214
230
  end
215
231
 
216
232
  # Returns Hash.
@@ -232,7 +248,8 @@ class Waithook
232
248
  uri = URI.parse(url)
233
249
  response = nil
234
250
 
235
- Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
251
+ http_options = {use_ssl: uri.scheme == 'https'}.merge(@forward_options || {})
252
+ Net::HTTP.start(uri.host, uri.port, http_options) do |http|
236
253
  http_klass = case method
237
254
  when "GET" then Net::HTTP::Get
238
255
  when "POST" then Net::HTTP::Post
@@ -263,3 +280,4 @@ class Waithook
263
280
  end
264
281
  end
265
282
  end
283
+
@@ -55,6 +55,20 @@ describe "Waithook" do
55
55
  assert_equal("POST", webhook.method)
56
56
  end
57
57
 
58
+ it "should use forward_options in request" do
59
+ waithook = default_client(forward_options: {write_timeout: :aaa, local_host: "--11"})
60
+
61
+ message = {'my_data' => true}
62
+
63
+ Excon.post("http://#{HOST}:#{PORT}/my-super-test", body: JSON.generate(message))
64
+
65
+ forward_error = begin
66
+ waithook.forward_to("http://#{HOST}:#{PORT}/my-super-test2")
67
+ rescue => e; e end
68
+ assert_equal(forward_error.class, Socket::ResolutionError)
69
+ assert_includes(forward_error.message, "getaddrinfo: nodename nor servname provided, or not known")
70
+ end
71
+
58
72
  it "should have trace log level" do
59
73
  out, err = capture_io do
60
74
  default_client(logger_level: :trace, logger: true)
@@ -96,4 +110,20 @@ describe "Waithook" do
96
110
 
97
111
  assert_includes(out, "Timeout::Error: execution expired")
98
112
  end
113
+
114
+ it "should throw exception when got socket error" do
115
+ waithook = default_client(logger: true)
116
+ socket = waithook.client.instance_variable_get(:@socket)
117
+ socket.close
118
+
119
+ captured_error = nil
120
+ begin
121
+ waithook.wait_message(raise_on_timeout: false)
122
+ rescue => error
123
+ captured_error = error
124
+ end
125
+
126
+ assert_instance_of(IOError, captured_error)
127
+ assert_equal("stream closed in another thread", captured_error.message)
128
+ end
99
129
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: waithook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Evstigneev
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-22 00:00:00.000000000 Z
10
+ date: 2025-03-10 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: websocket
@@ -55,7 +54,6 @@ homepage: https://github.com/paxa/waithook-ruby
55
54
  licenses:
56
55
  - MIT
57
56
  metadata: {}
58
- post_install_message:
59
57
  rdoc_options: []
60
58
  require_paths:
61
59
  - lib
@@ -70,8 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
68
  - !ruby/object:Gem::Version
71
69
  version: '0'
72
70
  requirements: []
73
- rubygems_version: 3.5.11
74
- signing_key:
71
+ rubygems_version: 3.6.5
75
72
  specification_version: 4
76
73
  summary: HTTP to WebSocket transmitting client
77
74
  test_files: []