splitclient-rb 8.9.0.pre.rc1-java → 8.10.0-java

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: dd476a208526c32175e7a10e734b1d2c8068e12e762694af6da1a40692f2f17a
4
- data.tar.gz: 161d0703482b5ac2f6b63eed534aa116591a17e11659575cfc7332a99401a40c
3
+ metadata.gz: fbfbcf5444639de1b0940978ab696d218c7ad2cf8801e5ae1f28a5399af45a50
4
+ data.tar.gz: a6cd50e2bdb8a7ff8c941630f1cd2ce5f9ed1a3f02fbc559ba807badfc3d3cf1
5
5
  SHA512:
6
- metadata.gz: dac3c87167c3fb35bb06a7f3210a34fdcb3dd4524062947dc3a8afeff14c9ae7d20b17fa2855d62267959eb88f41904beb94684a3cd94ac6f076e1ff2cb08768
7
- data.tar.gz: 8c36c12b0d57af4a5a243af76dac0efb004b587f441230c31306be58da95f3a4baa1d138588f43b92c1f5cb408678bd7d49c499c5f4841e19e117e58ae401772
6
+ metadata.gz: a7b7ebb55330d9c812b520786f067ced5c6d6c5da5311f0203b92ed338b241a1195cbd374d3ff6b5a5e08e3ca03f81ba830d2cffd9bdf0586397fef362327e34
7
+ data.tar.gz: 4ec00a7c3405421ba6ec0370b431861e44159ae23dbe6c77278d95b9b1366242cb27eee002cf19e85613627b0ea51ca2e54945ff08b44e4bb8b553d0e78509c4
@@ -35,6 +35,12 @@ jobs:
35
35
  with:
36
36
  fetch-depth: 0
37
37
 
38
+ - name: Set up Java
39
+ uses: actions/setup-java@v2
40
+ with:
41
+ java-version: 17
42
+ distribution: "temurin"
43
+
38
44
  - name: Setup Ruby ${{ matrix.version }}
39
45
  uses: ruby/setup-ruby@v1
40
46
  with:
@@ -57,7 +63,7 @@ jobs:
57
63
 
58
64
  - name: SonarQube Scan (Push)
59
65
  if: matrix.version == '3.2.2' && github.event_name == 'push'
60
- uses: SonarSource/sonarcloud-github-action@v1.9
66
+ uses: SonarSource/sonarcloud-github-action@v5.0.0
61
67
  env:
62
68
  SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
63
69
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -69,13 +75,14 @@ jobs:
69
75
 
70
76
  - name: SonarQube Scan (Pull Request)
71
77
  if: matrix.version == '3.2.2' && github.event_name == 'pull_request'
72
- uses: SonarSource/sonarcloud-github-action@v1.9
78
+ uses: SonarSource/sonarcloud-github-action@v5.0.0
73
79
  env:
74
80
  SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
75
81
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76
82
  with:
77
83
  projectBaseDir: .
78
84
  args: >
85
+ -Dsonar.java.source=17
79
86
  -Dsonar.host.url=${{ secrets.SONARQUBE_HOST }}
80
87
  -Dsonar.projectVersion=${{ env.VERSION }}
81
88
  -Dsonar.pullrequest.key=${{ github.event.pull_request.number }}
data/CHANGES.txt CHANGED
@@ -1,5 +1,11 @@
1
1
  CHANGES
2
2
 
3
+ 8.10.0 (Nov 28, 2025)
4
+ - Replaced socketry gem used in streaming feature with built-in socket lib.
5
+
6
+ 8.9.0 (Oct 8, 2025)
7
+ - Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs.
8
+
3
9
  8.8.0 (Sep 26, 2025)
4
10
  - Added a maximum size payload when posting unique keys telemetry in batches
5
11
 
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: false
2
2
 
3
- require 'socketry'
3
+ require 'socket'
4
+ require 'openssl'
4
5
  require 'uri'
6
+ require 'timeout'
5
7
 
6
8
  module SplitIoClient
7
9
  module SSE
@@ -36,12 +38,15 @@ module SplitIoClient
36
38
 
37
39
  def close(status = nil)
38
40
  unless connected?
39
- @config.logger.error('SSEClient already disconected.') if @config.debug_enabled
41
+ @config.logger.debug('SSEClient already disconected.')
40
42
  return
41
43
  end
44
+ @config.logger.debug("Closing SSEClient socket")
42
45
 
43
46
  @connected.make_false
44
- @socket&.close
47
+ @socket.sync_close = true if @socket.is_a? OpenSSL::SSL::SSLSocket
48
+ @socket.close
49
+ @config.logger.debug("SSEClient socket state #{@socket.state}") if @socket.is_a? OpenSSL::SSL::SSLSocket
45
50
  push_status(status)
46
51
  rescue StandardError => e
47
52
  @config.logger.error("SSEClient close Error: #{e.inspect}")
@@ -55,7 +60,6 @@ module SplitIoClient
55
60
 
56
61
  @uri = URI(url)
57
62
  latch = Concurrent::CountDownLatch.new(1)
58
-
59
63
  connect_thread(latch)
60
64
 
61
65
  return false unless latch.wait(CONNECT_TIMEOUT)
@@ -74,42 +78,73 @@ module SplitIoClient
74
78
 
75
79
  def connect_thread(latch)
76
80
  @config.threads[:connect_stream] = Thread.new do
77
- @config.logger.info('Starting connect_stream thread ...') if @config.debug_enabled
81
+ @config.logger.info('Starting connect_stream thread ...')
78
82
  new_status = connect_stream(latch)
79
83
  push_status(new_status)
80
- @config.logger.info('connect_stream thread finished.') if @config.debug_enabled
84
+ @config.logger.info('connect_stream thread finished.')
81
85
  end
82
86
  end
83
87
 
84
88
  def connect_stream(latch)
85
89
  return Constants::PUSH_NONRETRYABLE_ERROR unless socket_write(latch)
86
-
87
90
  while connected? || @first_event.value
88
- begin
89
- partial_data = @socket.readpartial(10_000, timeout: @read_timeout)
90
-
91
- read_first_event(partial_data, latch)
92
-
93
- raise 'eof exception' if partial_data == :eof
94
- rescue Errno::EBADF, IOError => e
95
- @config.logger.error(e.inspect) if @config.debug_enabled
96
- return nil
97
- rescue StandardError => e
98
- return nil if ENV['SPLITCLIENT_ENV'] == 'test'
99
-
100
- @config.logger.error("Error reading partial data: #{e.inspect}") if @config.debug_enabled
101
- return Constants::PUSH_RETRYABLE_ERROR
91
+ begin
92
+ if IO.select([@socket], nil, nil, @read_timeout)
93
+ begin
94
+ partial_data = @socket.readpartial(10_000)
95
+ read_first_event(partial_data, latch)
96
+
97
+ raise 'eof exception' if partial_data == :eof
98
+ rescue IO::WaitReadable => e
99
+ @config.logger.debug("SSE client IO::WaitReadable transient error: #{e.inspect}")
100
+ IO.select([@socket], nil, nil, @read_timeout)
101
+ retry
102
+ rescue Errno::EAGAIN => e
103
+ @config.logger.debug("SSE client transient error: #{e.inspect}")
104
+ IO.select([@socket], nil, nil, @read_timeout)
105
+ retry
106
+ rescue Errno::ETIMEDOUT => e
107
+ @config.logger.error("SSE read operation timed out!: #{e.inspect}")
108
+ return Constants::PUSH_RETRYABLE_ERROR
109
+ rescue EOFError => e
110
+ puts "SSE read operation EOF Exception!: #{e.inspect}"
111
+ @config.logger.error("SSE read operation EOF Exception!: #{e.inspect}")
112
+ raise 'eof exception'
113
+ rescue Errno::EBADF, IOError => e
114
+ @config.logger.error("SSE read operation EBADF or IOError: #{e.inspect}")
115
+ return Constants::PUSH_RETRYABLE_ERROR
116
+ rescue StandardError => e
117
+ @config.logger.error("SSE read operation StandardError: #{e.inspect}")
118
+ return nil if ENV['SPLITCLIENT_ENV'] == 'test'
119
+
120
+ @config.logger.error("Error reading partial data: #{e.inspect}")
121
+ return Constants::PUSH_RETRYABLE_ERROR
122
+ end
123
+ else
124
+ @config.logger.error("SSE read operation timed out, no data available.")
125
+ return Constants::PUSH_RETRYABLE_ERROR
126
+ end
127
+ rescue Errno::EBADF
128
+ @config.logger.debug("SSE socket is not connected (Errno::EBADF)")
129
+ break
130
+ rescue RuntimeError
131
+ raise 'eof exception'
132
+ rescue Exception => e
133
+ @config.logger.debug("SSE socket is not connected: #{e.inspect}")
134
+ break
102
135
  end
103
136
 
104
137
  process_data(partial_data)
105
138
  end
139
+ @config.logger.info("SSE read operation exited: #{connected?}")
140
+
106
141
  nil
107
142
  end
108
143
 
109
144
  def socket_write(latch)
110
145
  @first_event.make_true
111
146
  @socket = socket_connect
112
- @socket.write(build_request(@uri))
147
+ @socket.puts(build_request(@uri))
113
148
  true
114
149
  rescue StandardError => e
115
150
  @config.logger.error("Error during connecting to #{@uri.host}. Error: #{e.inspect}")
@@ -130,6 +165,7 @@ module SplitIoClient
130
165
 
131
166
  if response_code == OK_CODE && !error_event
132
167
  @connected.make_true
168
+ @config.logger.debug("SSE client first event Connected is true")
133
169
  @telemetry_runtime_producer.record_streaming_event(Telemetry::Domain::Constants::SSE_CONNECTION_ESTABLISHED, nil)
134
170
  push_status(Constants::PUSH_CONNECTED)
135
171
  end
@@ -138,15 +174,37 @@ module SplitIoClient
138
174
  end
139
175
 
140
176
  def socket_connect
141
- return Socketry::SSL::Socket.connect(@uri.host, @uri.port) if @uri.scheme.casecmp('https').zero?
177
+ tcp_socket = TCPSocket.new(@uri.host, @uri.port)
178
+ if @uri.scheme.casecmp('https').zero?
179
+ begin
180
+ ssl_context = OpenSSL::SSL::SSLContext.new
181
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
182
+ ssl_socket.hostname = @uri.host
183
+
184
+ begin
185
+ ssl_socket.connect_nonblock
186
+ rescue IO::WaitReadable
187
+ IO.select([ssl_socket])
188
+ retry
189
+ rescue IO::WaitWritable
190
+ IO.select(nil, [ssl_socket])
191
+ retry
192
+ end
193
+ return ssl_socket
194
+
195
+ rescue Exception => e
196
+ @config.logger.error("socket connect error: #{e.inspect}")
197
+ return nil
198
+ end
199
+ end
142
200
 
143
- Socketry::TCP::Socket.connect(@uri.host, @uri.port)
201
+ tcp_socket
144
202
  end
145
203
 
146
204
  def process_data(partial_data)
205
+ @config.logger.debug("Event partial data: #{partial_data}")
147
206
  return if partial_data.nil? || partial_data == KEEP_ALIVE_RESPONSE
148
207
 
149
- @config.logger.debug("Event partial data: #{partial_data}") if @config.debug_enabled
150
208
  events = @event_parser.parse(partial_data)
151
209
  events.each { |event| process_event(event) }
152
210
  rescue StandardError => e
@@ -162,7 +220,7 @@ module SplitIoClient
162
220
  req << "SplitSDKMachineName: #{@config.machine_name}\r\n"
163
221
  req << "SplitSDKClientKey: #{@api_key.split(//).last(4).join}\r\n" unless @api_key.nil?
164
222
  req << "Cache-Control: no-cache\r\n\r\n"
165
- @config.logger.debug("Request info: #{req}") if @config.debug_enabled
223
+ @config.logger.debug("Request info: #{req}")
166
224
  req
167
225
  end
168
226
 
@@ -57,8 +57,12 @@ module SplitIoClient
57
57
  end
58
58
  without_nil = Array.new
59
59
  flag_sets.each { |flag_set|
60
- without_nil.push(flag_set) if !flag_set.nil?
61
- log_nil("flag set", method) if flag_set.nil?
60
+ if !flag_set.nil?
61
+ without_nil.push(flag_set)
62
+ next
63
+ end
64
+
65
+ log_nil("flag set", method)
62
66
  }
63
67
  if without_nil.length() == 0
64
68
  log_invalid_flag_set_type(method)
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '8.9.0-rc1'
2
+ VERSION = '8.10.0'
3
3
  end
@@ -2,4 +2,5 @@ sonar.projectKey=ruby-client
2
2
  sonar.projectKey=ruby-client
3
3
  sonar.sources=lib
4
4
  sonar.tests=spec
5
+ sonar.java.source=17
5
6
  sonar.ruby.coverage.reportPaths=coverage/.resultset.sonarqube.json
@@ -59,6 +59,5 @@ Gem::Specification.new do |spec|
59
59
  spec.add_runtime_dependency 'lru_redux', '~> 1.1'
60
60
  spec.add_runtime_dependency 'net-http-persistent', '>= 2.9', '< 5.0'
61
61
  spec.add_runtime_dependency 'redis', '>= 4.0.0', '< 6.0'
62
- spec.add_runtime_dependency 'socketry', '>= 0.4', '< 1.0'
63
62
  spec.add_runtime_dependency 'thread_safe', '~> 0.3'
64
63
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splitclient-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.9.0.pre.rc1
4
+ version: 8.10.0
5
5
  platform: java
6
6
  authors:
7
7
  - Split Software
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-10-08 00:00:00.000000000 Z
10
+ date: 2025-11-26 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: allocation_stats
@@ -361,26 +361,6 @@ dependencies:
361
361
  - - "<"
362
362
  - !ruby/object:Gem::Version
363
363
  version: '6.0'
364
- - !ruby/object:Gem::Dependency
365
- name: socketry
366
- requirement: !ruby/object:Gem::Requirement
367
- requirements:
368
- - - ">="
369
- - !ruby/object:Gem::Version
370
- version: '0.4'
371
- - - "<"
372
- - !ruby/object:Gem::Version
373
- version: '1.0'
374
- type: :runtime
375
- prerelease: false
376
- version_requirements: !ruby/object:Gem::Requirement
377
- requirements:
378
- - - ">="
379
- - !ruby/object:Gem::Version
380
- version: '0.4'
381
- - - "<"
382
- - !ruby/object:Gem::Version
383
- version: '1.0'
384
364
  - !ruby/object:Gem::Dependency
385
365
  name: thread_safe
386
366
  requirement: !ruby/object:Gem::Requirement