protocol-zmtp 0.10.0 → 0.10.2

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: 303ee019ebede5cddca93226c136233c19b7ec6e54cad7ef0deba5f5a5f6e347
4
- data.tar.gz: 229f46c1a06f1fe7d02a3b1a518fee8958786959fa0b43fe6587d47392c9d602
3
+ metadata.gz: a99947180a584a86331021fac44327f3bde68cc44c50fe6264fdb7e6018cf3af
4
+ data.tar.gz: 00c1b152a3763603452a42b0af92455ab02cb864d55b4cd331d0dba26396f65b
5
5
  SHA512:
6
- metadata.gz: 38345cf8abc4d1ed198a90abe714d15dd5cc8877fd22ba25f672c9ff4c02a36e9c7754a6c3998fc3b0cf9dd8972e54595be4c953c4e18d0acecaf3363b5971d2
7
- data.tar.gz: 50c74c72d1926d1bd3756cf130d57039337f75f34c47d701b7b7a936e9f3d9b57e9f203e6b841b454b9de5d99624ada8239dbfb6e2f8cf8285ae991aa94b9828
6
+ metadata.gz: 6e6997a555bc1ed27bd68f51935cfc0b68bf4b7b3f5055a47b2de44f63561116b309be5d933df1ffc9e8a62d72deac7a3ed918b9b323fcb41584934a8b76a684
7
+ data.tar.gz: 5a495e661e2e4c829a6e33d5cb3d98a0976c4606efb676f17201a7184a82753405816d7f66057154b95a2af78c3385d960e1d0a319674945454eb2218f8c81fd
@@ -80,6 +80,7 @@ module Protocol
80
80
  # writes in place so the per-message 2-or-9 byte String allocation
81
81
  # in write_frames disappears on the hot send path.
82
82
  @header_buf = String.new(capacity: 9, encoding: Encoding::BINARY)
83
+ @frame_buf = String.new(capacity: 257, encoding: Encoding::BINARY)
83
84
  end
84
85
 
85
86
 
@@ -188,6 +189,25 @@ module Protocol
188
189
  end
189
190
 
190
191
 
192
+ # Writes multiple pre-encoded wire byte strings under a single
193
+ # mutex acquisition.
194
+ #
195
+ # @param wire_strings [Array<String>]
196
+ # @return [void]
197
+ def write_wire_batch(wire_strings)
198
+ with_deferred_cancel do
199
+ @mutex.synchronize do
200
+ i = 0
201
+ n = wire_strings.size
202
+ while i < n
203
+ @io.write(wire_strings[i])
204
+ i += 1
205
+ end
206
+ end
207
+ end
208
+ end
209
+
210
+
191
211
  # Returns true if the ZMTP mechanism encrypts at the frame level
192
212
  # (e.g. CURVE, BLAKE3ZMQ).
193
213
  #
@@ -316,11 +336,10 @@ module Protocol
316
336
  private
317
337
 
318
338
  # Defers task cancellation around a block of wire writes so the
319
- # peer never sees a half-written frame. Without this, an
320
- # +Async::Cancel+ arriving between the header write and the body
321
- # write (the unencrypted path issues two separate +@io.write+
322
- # calls per frame) would desync the peer's framer
323
- # unrecoverably.
339
+ # peer never sees a half-written frame or partial multipart
340
+ # message. Without this, an +Async::Cancel+ arriving between
341
+ # successive frames (or between header and body writes for long
342
+ # frames) would desync the peer's framer unrecoverably.
324
343
  #
325
344
  # When called outside an Async task (test fixtures, blocking
326
345
  # callers), the block runs directly -- there is no task to defer
@@ -337,15 +356,16 @@ module Protocol
337
356
 
338
357
  # Writes message parts as ZMTP frames, encrypting if needed.
339
358
  #
340
- # For the unencrypted path, writes the frame header and body
341
- # separately to the IO instead of allocating a wire String. This
342
- # avoids copying the body just to glue a 1- or 9-byte header onto
343
- # it -- significant for large messages where the body copy was
344
- # the dominant allocation per send.
359
+ # Short frames (body <= 255 B) combine the 2-byte header and
360
+ # body into a reusable buffer for a single +@io.write+, halving
361
+ # the per-frame mutex overhead in io-stream. Long frames write
362
+ # header and body separately to avoid copying the body.
345
363
  def write_frames(parts)
346
- encrypted = @mechanism.encrypted?
347
- buf = @header_buf
348
- last = parts.size - 1
364
+ encrypted = @mechanism.encrypted?
365
+ buf = @header_buf
366
+ fbuf = @frame_buf
367
+ flag_bytes = Codec::Frame::FLAG_BYTES
368
+ last = parts.size - 1
349
369
 
350
370
  i = 0
351
371
 
@@ -361,16 +381,18 @@ module Protocol
361
381
  size = body.bytesize
362
382
  flags = more ? Codec::Frame::FLAGS_MORE : 0
363
383
 
364
- buf.clear
365
-
366
384
  if size > Codec::Frame::SHORT_MAX
385
+ buf.clear
367
386
  [flags | Codec::Frame::FLAGS_LONG, size].pack("CQ>", buffer: buf)
387
+ @io.write(buf)
388
+ @io.write(body)
368
389
  else
369
- [flags, size].pack("CC", buffer: buf)
390
+ fbuf.clear
391
+ fbuf << flag_bytes[flags]
392
+ fbuf << flag_bytes[size]
393
+ fbuf << body
394
+ @io.write(fbuf)
370
395
  end
371
-
372
- @io.write(buf)
373
- @io.write(body)
374
396
  end
375
397
 
376
398
  i += 1
@@ -26,7 +26,7 @@ module Protocol
26
26
  # @return [Hash] { peer_socket_type:, peer_identity:, peer_public_key:, peer_properties:, peer_major:, peer_minor: }
27
27
  # @raise [Error]
28
28
  def handshake!(io, as_server:, socket_type:, identity:, metadata: nil)
29
- io.write(Codec::Greeting.encode(mechanism: MECHANISM_NAME, as_server: as_server))
29
+ io.write(Codec::Greeting.encode(mechanism: MECHANISM_NAME, as_server: false))
30
30
  io.flush
31
31
 
32
32
  peer_greeting = Codec::Greeting.read_from(io)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Protocol
4
4
  module ZMTP
5
- VERSION = "0.10.0"
5
+ VERSION = "0.10.2"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-zmtp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger
@@ -53,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  requirements: []
56
- rubygems_version: 4.0.6
56
+ rubygems_version: 4.0.10
57
57
  specification_version: 4
58
58
  summary: ZMTP 3.1 wire protocol codec and connection
59
59
  test_files: []