journaled 6.2.7 → 6.2.8

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: f07fe3feaecd8dc11436c7d8df5810568b00286ec542f95a858cb21ee6d3ccc3
4
- data.tar.gz: 9bda790056d6fc66e7325a9870fd3034a6e7b861ed2d42205f976fc6eaccc386
3
+ metadata.gz: '087e1092ce9f8937951563934335c344f2fd3be2e1b2c00638f7f9858d43aa2f'
4
+ data.tar.gz: 706e1931d2411dfb20e5558b6a1bd8d873e69fb4af31238387d09ea9aacd7988
5
5
  SHA512:
6
- metadata.gz: 1cc2d0a52e9390e94b52c95e07b38c92308e73deb0e29aefab06ccdeb612034a7ecc8f0a06bb4bff04472e7fff748168e3bb4ac82fe899d3eb3d861609b4110f
7
- data.tar.gz: a475ca2bfc321824ce531f7d716b769c523acd70e0ed6d9e382d6618f52d6e4bf76baa1b75af2ed036af36f5eaa1c8f5176bd5ecff9530c7477800d3e4dc480d
6
+ metadata.gz: 5bb28caee44bb06d03d37aad85b8653947947017fc10c247ce23bff032226ef852810fbb4357bef07df8cffa885e3260086ec12900da2284e7e5939eff0ab887
7
+ data.tar.gz: 571e2176d4bb3c8e8690e7fd6a46af587e85c0790ff59e3efe2f8034c040d9fce7acb2a0f6e9153d5d49a7b372cecafebac0c5bbe1252f0510a2ecd4ba919fd5
@@ -15,7 +15,8 @@ module Journaled
15
15
  'ValidationException',
16
16
  ].freeze
17
17
 
18
- BATCH_TOO_LARGE_PATTERN = /too large/i
18
+ # Kinesis rejects any record whose data blob exceeds 1 MB.
19
+ KINESIS_MAX_RECORD_BYTES = 1_048_576
19
20
 
20
21
  # Send a batch of database events to Kinesis
21
22
  #
@@ -43,9 +44,7 @@ module Journaled
43
44
  response = kinesis_client.put_records(stream_name:, records:)
44
45
  process_response(response, stream_events)
45
46
  rescue Aws::Kinesis::Errors::ValidationException => e
46
- raise unless e.message.match?(BATCH_TOO_LARGE_PATTERN)
47
-
48
- handle_batch_too_large(stream_name, stream_events)
47
+ handle_validation_error(stream_name, stream_events, e.message)
49
48
  rescue StandardError => e
50
49
  # Handle transient errors (throttling, network issues, service unavailable)
51
50
  handle_transient_batch_error(e, stream_events)
@@ -94,16 +93,19 @@ module Journaled
94
93
  )
95
94
  end
96
95
 
97
- def handle_batch_too_large(stream_name, stream_events)
96
+ # Isolate the offending record(s) when Kinesis rejects the batch with a
97
+ # ValidationException (aggregate payload too large, per-record size limit,
98
+ # invalid partition key, etc.). Splits the batch in half and retries
99
+ # recursively until a single offending event is marked as a permanent failure.
100
+ def handle_validation_error(stream_name, stream_events, error_message)
98
101
  if stream_events.size <= 1
99
- # Single event exceeds payload limit — treat as permanent failure
100
102
  return {
101
103
  succeeded: [],
102
104
  failed: stream_events.map do |event|
103
105
  create_failed_event(
104
106
  event,
105
107
  error_code: 'ValidationException',
106
- error_message: 'Record exceeds Kinesis payload limit',
108
+ error_message:,
107
109
  transient: false,
108
110
  )
109
111
  end,
@@ -111,7 +113,8 @@ module Journaled
111
113
  end
112
114
 
113
115
  Rails.logger.warn(
114
- "[journaled] Batch too large for Kinesis (#{stream_events.size} events), splitting in half and retrying",
116
+ "[journaled] Kinesis ValidationException for batch of #{stream_events.size} events " \
117
+ "(#{error_message}), splitting in half and retrying",
115
118
  )
116
119
 
117
120
  mid = stream_events.size / 2
@@ -14,6 +14,7 @@ module Journaled
14
14
  # 4. Start workers: bundle exec rake journaled_worker:work
15
15
  class Adapter < Journaled::DeliveryAdapter
16
16
  class TableNotFoundError < StandardError; end
17
+ class RecordTooLargeError < StandardError; end
17
18
 
18
19
  # Delivers events by inserting them into the database
19
20
  #
@@ -29,6 +30,15 @@ module Journaled
29
30
  # Exclude the application-level id - the database will generate its own using uuid_generate_v7()
30
31
  event_data = event.journaled_attributes.except(:id)
31
32
 
33
+ # The DB-generated id adds bytes to the JSON payload at send time, so a
34
+ # placeholder id keeps this estimate honest.
35
+ payload_bytesize = event_data.merge(id: SecureRandom.uuid).to_json.bytesize
36
+ if payload_bytesize > KinesisBatchSender::KINESIS_MAX_RECORD_BYTES
37
+ raise RecordTooLargeError, "Journaled event '#{event.journaled_attributes[:event_type]}' " \
38
+ "exceeds Kinesis #{KinesisBatchSender::KINESIS_MAX_RECORD_BYTES}-byte per-record limit " \
39
+ "(#{payload_bytesize} bytes); refusing to enqueue."
40
+ end
41
+
32
42
  {
33
43
  event_type: event.journaled_attributes[:event_type],
34
44
  event_data:,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Journaled
4
- VERSION = "6.2.7"
4
+ VERSION = "6.2.8"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: journaled
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.2.7
4
+ version: 6.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jake Lipson
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2026-04-20 00:00:00.000000000 Z
14
+ date: 2026-06-02 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activejob