activeitem 0.0.12 → 0.0.13

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: c2eafbb256db7671d0e2977ebbfd4ef41b7660085086d6221dd0e901743611b8
4
- data.tar.gz: e5071976ee269c11a3c1ad52ee3a1ada4dfcf67e260956a03525bfbbab40a29d
3
+ metadata.gz: e20ffb5a359af1d27e15e389e30505d40a742edbe2c9c98ab76e4498fd70239e
4
+ data.tar.gz: 031b9d01ad6f636f1fb27c4752e36b10eedecf2d3909b2e11939f4c49368db4a
5
5
  SHA512:
6
- metadata.gz: dc74fd0eb4b4f00e22ceb802b5814eec809e8bdc61fb8d7d2e2b3d3d38974512b352a8234b75e470204fc18b895d38e09877984b260c35b4a4949d32ab0293f6
7
- data.tar.gz: 7f9036291b93d5904dba79d9fcd7bbc1c265d0f901b27548861361c4a9c15cda50138dec15f06218c61ce7b4a43bf0ed01f420ae1d5882fa4de28f57420d21aa
6
+ metadata.gz: a6bc6e95cc4f1a87c81bf6afc15191a43bbdd037ac8fdf98dd2216585ab21903eaca17c30b6ce9e41f1e4ae5f4a01c31d8992cab1a628d132e7c0e9dadf911f2
7
+ data.tar.gz: 19b6490facb7f9b3fa4224ab7e97867b65fde49fa99da5c202eec89db36f1da6b7dc70ec1bae53d5fc5f4003a2628db0f071120f88b6ec1a1074d4eada5a0646
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.0.13
4
+
5
+ ### Changed
6
+
7
+ - **Configuration defaults from ENV** — `table_prefix` now defaults to `ENV['APP_NAME']` and `environment` defaults to `ENV['ENVIRONMENT']` instead of `nil`. Explicit `.configure` calls still override. This eliminates the boilerplate `ActiveItem.configure` block in most Belt apps.
8
+
3
9
  ## 0.0.9
4
10
 
5
11
  ### Fixed
@@ -10,8 +10,8 @@ module ActiveItem
10
10
 
11
11
  def initialize
12
12
  @logger = NullLogger.new
13
- @table_prefix = nil
14
- @environment = nil
13
+ @table_prefix = ENV.fetch('APP_NAME', nil)
14
+ @environment = ENV.fetch('ENVIRONMENT', nil)
15
15
  end
16
16
 
17
17
  # Generates table name from model class name using configured prefix/env
@@ -18,6 +18,19 @@ module ActiveItem
18
18
  end
19
19
  end
20
20
 
21
+ # Raised when batch_write fails to write all items after retries.
22
+ class BatchWriteError < StandardError
23
+ attr_reader :model_name, :table, :failed_count, :total_count
24
+
25
+ def initialize(model_name:, table:, failed_count:, total_count:)
26
+ @model_name = model_name
27
+ @table = table
28
+ @failed_count = failed_count
29
+ @total_count = total_count
30
+ super("#{model_name} batch_write failed: #{failed_count} of #{total_count} items could not be written to #{table} after retries (DynamoDB throughput exceeded).")
31
+ end
32
+ end
33
+
21
34
  # Raised by destroy! when the record is not destroyed.
22
35
  class RecordNotDestroyed < StandardError
23
36
  attr_reader :record
@@ -87,6 +87,8 @@ module ActiveItem
87
87
  record.instance_variable_set(:@updated_at, now)
88
88
  end
89
89
 
90
+ failed_count = 0
91
+
90
92
  # DynamoDB BatchWriteItem limit is 25 items per request
91
93
  records.each_slice(25) do |chunk|
92
94
  write_requests = chunk.map do |record|
@@ -94,7 +96,7 @@ module ActiveItem
94
96
  end
95
97
 
96
98
  request = { table_name => write_requests }
97
- max_retries = 5
99
+ max_retries = 8
98
100
  retries = 0
99
101
 
100
102
  while request&.any?
@@ -104,7 +106,11 @@ module ActiveItem
104
106
  break unless unprocessed&.any?
105
107
 
106
108
  retries += 1
107
- break if retries > max_retries
109
+ if retries > max_retries
110
+ # Count items that could not be written after all retries
111
+ unprocessed.each_value { |reqs| failed_count += reqs.size }
112
+ break
113
+ end
108
114
 
109
115
  sleep(0.05 * (2**retries) * (0.5 + (rand * 0.5)))
110
116
  request = unprocessed
@@ -112,6 +118,15 @@ module ActiveItem
112
118
  end
113
119
  end
114
120
 
121
+ if failed_count.positive?
122
+ raise ActiveItem::BatchWriteError.new(
123
+ model_name: name,
124
+ table: table_name,
125
+ failed_count: failed_count,
126
+ total_count: records.size
127
+ )
128
+ end
129
+
115
130
  records.each { |r| r.instance_variable_set(:@new_record, false) }
116
131
  records
117
132
  rescue Aws::DynamoDB::Errors::AccessDeniedException => e
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveItem
4
- VERSION = '0.0.12'
4
+ VERSION = '0.0.13'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeitem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2026-07-23 00:00:00.000000000 Z
12
+ date: 2026-07-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -67,6 +67,26 @@ dependencies:
67
67
  - - ">="
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: parallel
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '1.10'
77
+ - - "<"
78
+ - !ruby/object:Gem::Version
79
+ version: '2'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '1.10'
87
+ - - "<"
88
+ - !ruby/object:Gem::Version
89
+ version: '2'
70
90
  - !ruby/object:Gem::Dependency
71
91
  name: parallel_tests
72
92
  requirement: !ruby/object:Gem::Requirement