pgmq-ruby 0.4.0 → 0.5.0

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: a6b6b3dcddd3785167a0fd8482fb0900f0d51c9c5cf68ddd23b60e84eb306012
4
- data.tar.gz: 94604bf7c55a2bd62a63486278641c247b0a9d9cf3b50379d30ee0b7c8c840f4
3
+ metadata.gz: 5648229b33f490f7228d7f9b106fb40939632c6effff094d028d9f7dd5fc045a
4
+ data.tar.gz: 7a7d0ae6dd7ee59cf329093f4772e8cd8706e25be0e627defca60f3983e96084
5
5
  SHA512:
6
- metadata.gz: 3ea99c27e92f96f137c9552985830949cdff6538409646ddf6b10e587c05c2b831c8c083570996ff2c0ffbefd09ae01fa84002e2ca9093f0a27ec6f7387a2b59
7
- data.tar.gz: 437713bad4d37ff821487493097c6229b8c2069b260b74e587b3452f74508392b1dba7cf37ee3dd91c52143a4c147db373035351a8dc0d86f1d6cd70a4370d4d
6
+ metadata.gz: 5da9b67730f7c1b58af6be47c2364092988823b2c536e762ca56cc91bd5f27d2d678aef116373c7f0c62fec5037438f30ae0482979c0df3f9414aa3e5f41987a
7
+ data.tar.gz: 7c892fcc8d30d306670b7dd3fd3a3e3f70f573916b3e6526e0833a59acad85cdd44fcf830fd327ccba6608fe0e30eb072d2adc1bcb287ccc28c388e743cfd19e
@@ -64,7 +64,7 @@ jobs:
64
64
  run: rm -f Gemfile.lock
65
65
 
66
66
  - name: Set up Ruby
67
- uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0
67
+ uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
68
68
  with:
69
69
  ruby-version: ${{ matrix.ruby }}
70
70
  bundler-cache: true
@@ -102,57 +102,77 @@ jobs:
102
102
  GITHUB_COVERAGE: ${{ matrix.coverage }}
103
103
  run: bundle exec rspec
104
104
 
105
+ - name: Run examples
106
+ env:
107
+ PG_HOST: localhost
108
+ PG_PORT: 5433
109
+ PG_DATABASE: pgmq_test
110
+ PG_USER: postgres
111
+ PG_PASSWORD: postgres
112
+ run: bundle exec rake examples
113
+
105
114
  yard-lint:
106
115
  timeout-minutes: 5
107
116
  runs-on: ubuntu-latest
108
117
  strategy:
109
118
  fail-fast: false
119
+ env:
120
+ BUNDLE_GEMFILE: Gemfile.lint
110
121
  steps:
111
122
  - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
112
123
  with:
113
124
  fetch-depth: 0
114
- - name: Remove Gemfile.lock for Ruby 4.0
115
- run: rm -f Gemfile.lock
116
125
  - name: Set up Ruby
117
- uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0
126
+ uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
118
127
  with:
119
128
  ruby-version: '4.0.0'
120
129
  bundler-cache: true
121
130
  - name: Run yard-lint
122
131
  run: bundle exec yard-lint lib/
123
132
 
124
- coditsu:
133
+ rubocop:
125
134
  timeout-minutes: 5
126
135
  runs-on: ubuntu-latest
127
- strategy:
128
- fail-fast: false
136
+ env:
137
+ BUNDLE_GEMFILE: Gemfile.lint
129
138
  steps:
130
139
  - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
131
140
  with:
132
141
  fetch-depth: 0
133
- - name: Download Coditsu script
134
- run: |
135
- curl -sSL https://api.coditsu.io/run/ci -o coditsu_script.sh
136
- chmod +x coditsu_script.sh
137
- - name: Verify Coditsu script checksum
138
- run: |
139
- EXPECTED_SHA256="0aecc5aa010f53fca264548a41467a2b0a1208d750ce1da3e98a217304cacbbc"
140
- ACTUAL_SHA256=$(sha256sum coditsu_script.sh | awk '{ print $1 }')
141
- if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then
142
- echo "::error::Checksum verification failed. Expected $EXPECTED_SHA256 but got $ACTUAL_SHA256."
143
- exit 1
144
- fi
145
- - name: Run Coditsu
146
- run: ./coditsu_script.sh
142
+ - name: Set up Ruby
143
+ uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
144
+ with:
145
+ ruby-version: '4.0.0'
146
+ bundler-cache: true
147
+ - name: Run rubocop
148
+ run: bundle exec rubocop
149
+
150
+ lostconf:
151
+ timeout-minutes: 5
152
+ runs-on: ubuntu-latest
153
+ steps:
154
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
155
+ with:
156
+ fetch-depth: 0
157
+ - name: Set up Node.js
158
+ uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
159
+ with:
160
+ node-version: '20'
161
+ cache: 'npm'
162
+ - name: Install dependencies
163
+ run: npm ci
164
+ - name: Run lostconf
165
+ run: npx lostconf --fail-on-stale
147
166
 
148
167
  ci-success:
149
168
  name: CI Success
150
169
  runs-on: ubuntu-latest
151
170
  if: always()
152
171
  needs:
153
- - coditsu
172
+ - rubocop
154
173
  - specs
155
174
  - yard-lint
175
+ - lostconf
156
176
  steps:
157
177
  - name: Check all jobs passed
158
178
  if: |
@@ -24,7 +24,7 @@ jobs:
24
24
  fetch-depth: 0
25
25
 
26
26
  - name: Set up Ruby
27
- uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0
27
+ uses: ruby/setup-ruby@90be1154f987f4dc0fe0dd0feedac9e473aa4ba8 # v1.286.0
28
28
  with:
29
29
  bundler-cache: false
30
30
 
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --require spec_helper
2
+ --exclude-pattern spec/integration/**/*
data/.rubocop.yml ADDED
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ plugins:
4
+ - rubocop-capybara
5
+ - rubocop-factory_bot
6
+ - rubocop-performance
7
+ - rubocop-rspec
8
+ - rubocop-rspec_rails
9
+
10
+ inherit_gem:
11
+ standard: config/base.yml
12
+ standard-performance: config/base.yml
13
+ standard-rspec: config/base.yml
14
+
15
+ AllCops:
16
+ NewCops: enable
17
+ TargetRubyVersion: 3.2
18
+ Include:
19
+ - "**/*.rb"
20
+ - "**/*.gemspec"
21
+ - "**/Gemfile"
22
+ - "**/Rakefile"
23
+ - Gemfile.lint
24
+
25
+ # Disabled departments - not a Rails project, no Capybara/FactoryBot
26
+ Capybara:
27
+ Enabled: false
28
+
29
+ FactoryBot:
30
+ Enabled: false
31
+
32
+ RSpecRails:
33
+ Enabled: false
34
+
35
+ # Layout
36
+ Layout/LineLength:
37
+ Max: 120
38
+
39
+ Layout/SpaceInsideHashLiteralBraces:
40
+ EnforcedStyle: space
41
+
42
+ # RSpec - exclude integration examples (they use ExampleHelper, not RSpec)
43
+ RSpec:
44
+ Exclude:
45
+ - spec/integration/**/*
46
+
47
+ RSpec/ExampleLength:
48
+ Enabled: false
49
+
50
+ RSpec/IndexedLet:
51
+ Enabled: false
52
+
53
+ RSpec/MultipleExpectations:
54
+ Enabled: false
55
+
56
+ RSpec/MultipleMemoizedHelpers:
57
+ Max: 20
58
+
59
+ RSpec/NestedGroups:
60
+ Max: 4
61
+
62
+ RSpec/NoExpectationExample:
63
+ Enabled: false
64
+
65
+ RSpec/SpecFilePathFormat:
66
+ Enabled: false
data/.yard-lint.yml CHANGED
@@ -7,12 +7,10 @@ AllValidators:
7
7
  - "--private"
8
8
  - "--protected"
9
9
  Exclude:
10
- - "\\.git"
10
+ - .git/**/*
11
11
  - vendor/**/*
12
12
  - node_modules/**/*
13
13
  - spec/**/*
14
- - test/**/*
15
- - benchmark/**/*
16
14
  FailOnSeverity: convention
17
15
  RequiredCoverage: 100
18
16
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0 (2026-02-24)
4
+
5
+ ### Breaking Changes
6
+ - **[Breaking]** Remove `detach_archive(queue_name)` method. PGMQ 2.0 no longer requires archive table detachment as archive tables are no longer member objects. The server-side function was already a no-op in PGMQ 2.0+.
7
+ - **[Breaking]** Rename `vt_offset:` parameter to `vt:` in `set_vt`, `set_vt_batch`, and `set_vt_multi` methods. The `vt:` parameter now accepts either an integer offset (seconds from now) or an absolute `Time` object for PGMQ v1.11.0+.
8
+
9
+ ### PGMQ v1.11.0 Features
10
+ - **[Feature]** Add `last_read_at` field to `PGMQ::Message`. Returns the timestamp of the last read operation for the message, or nil if the message has never been read. This enables tracking when messages were last accessed (PGMQ v1.8.1+).
11
+ - **[Feature]** Add Grouped Round-Robin reading for fair message processing:
12
+ - `read_grouped_rr(queue_name, vt:, qty:)` - Read messages in round-robin order across groups
13
+ - `read_grouped_rr_with_poll(queue_name, vt:, qty:, max_poll_seconds:, poll_interval_ms:)` - With long-polling
14
+
15
+ Messages are grouped by the first key in their JSON payload. This ensures fair processing
16
+ when multiple entities (users, orders, etc.) have messages in the queue, preventing any
17
+ single entity from monopolizing workers.
18
+ - **[Feature]** Add Topic Routing support (AMQP-like patterns). New methods in `PGMQ::Client`:
19
+ - `bind_topic(pattern, queue_name)` - Bind a topic pattern to a queue
20
+ - `unbind_topic(pattern, queue_name)` - Remove a topic binding
21
+ - `produce_topic(routing_key, message, headers:, delay:)` - Send message via routing key
22
+ - `produce_batch_topic(routing_key, messages, headers:, delay:)` - Batch send via routing key
23
+ - `list_topic_bindings(queue_name:)` - List all topic bindings
24
+ - `test_routing(routing_key)` - Test which queues a routing key matches
25
+ - `validate_routing_key(routing_key)` - Validate a routing key
26
+ - `validate_topic_pattern(pattern)` - Validate a topic pattern
27
+
28
+ Topic patterns support wildcards: `*` (single word) and `#` (zero or more words).
29
+ Requires PGMQ v1.11.0+.
30
+
31
+ ### Testing
32
+ - **[Feature]** Add Fiber Scheduler integration tests demonstrating compatibility with Ruby's Fiber Scheduler API and the `async` gem for concurrent I/O operations.
33
+
34
+ ### Infrastructure
35
+ - **[Fix]** Update docker-compose.yml volume mount for PostgreSQL 18+ compatibility.
36
+ - **[Change]** Replace Coditsu with StandardRB for code linting. This provides faster, more consistent linting using the community Ruby Style Guide.
37
+
3
38
  ## 0.4.0 (2025-12-26)
4
39
 
5
40
  ### Breaking Changes
data/CLAUDE.md ADDED
@@ -0,0 +1,310 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ PGMQ-Ruby is a **low-level Ruby client** for PGMQ (PostgreSQL Message Queue), analogous to how rdkafka-ruby relates to Kafka. It provides direct 1:1 wrappers for PGMQ SQL functions as a thin transport layer.
8
+
9
+ This is **NOT** a full job processing framework. Framework features (instrumentation, job processing, Rails ActiveJob, retry strategies, monitoring integrations) belong in the planned `pgmq-framework` gem.
10
+
11
+ **Key Design Principles:**
12
+ - Thin wrapper around PGMQ SQL functions (low-level primitives only)
13
+ - Thread-safe connection pooling (transport layer)
14
+ - PostgreSQL transaction support (database primitive, not framework abstraction)
15
+ - Framework-agnostic (works with Rails, Sinatra, plain Ruby)
16
+ - Minimal dependencies (only `pg` and `connection_pool`)
17
+ - No instrumentation/observability layer (framework concern)
18
+
19
+ ## Development Commands
20
+
21
+ ### Testing
22
+
23
+ ```bash
24
+ # Start PostgreSQL with PGMQ extension (required for tests)
25
+ docker compose up -d
26
+
27
+ # Run all tests
28
+ bundle exec rspec
29
+
30
+ # Run specific test file
31
+ bundle exec rspec spec/unit/client_spec.rb
32
+
33
+ # Run integration tests only
34
+ bundle exec rspec spec/integration
35
+
36
+ # Run single test by line number
37
+ bundle exec rspec spec/unit/client_spec.rb:42
38
+ ```
39
+
40
+ **Important:** PostgreSQL runs on port **5433** locally (see docker-compose.yml) to avoid conflicts with system PostgreSQL. Tests use this port automatically.
41
+
42
+ ### Code Quality
43
+
44
+ ```bash
45
+ # Run tests
46
+ bundle exec rspec
47
+ ```
48
+
49
+
50
+ ### Interactive Development
51
+
52
+ ```bash
53
+ # Start IRB console with PGMQ loaded
54
+ bundle exec bin/console
55
+
56
+ # Console automatically connects to test database at localhost:5433
57
+ ```
58
+
59
+ ## Architecture
60
+
61
+ ### Core Components
62
+
63
+ 1. **PGMQ::Client** (`lib/pgmq/client.rb`)
64
+ - Main interface for all PGMQ operations (modular architecture, ~130 lines)
65
+ - Delegates connection management to PGMQ::Connection
66
+ - Validates queue names (48 char max, PostgreSQL identifier rules)
67
+ - Composed of 8 functional modules for separation of concerns:
68
+ - **Transaction** (`lib/pgmq/transaction.rb`) - PostgreSQL transaction support
69
+ - **QueueManagement** (`lib/pgmq/client/queue_management.rb`) - Queue lifecycle (create, drop, list)
70
+ - **Producer** (`lib/pgmq/client/producer.rb`) - Message sending operations
71
+ - **Consumer** (`lib/pgmq/client/consumer.rb`) - Single-queue reading operations
72
+ - **MultiQueue** (`lib/pgmq/client/multi_queue.rb`) - Multi-queue operations (UNION ALL)
73
+ - **MessageLifecycle** (`lib/pgmq/client/message_lifecycle.rb`) - Message state transitions (pop, delete, archive, set_vt)
74
+ - **Maintenance** (`lib/pgmq/client/maintenance.rb`) - Queue maintenance (purge, notifications)
75
+ - **Metrics** (`lib/pgmq/client/metrics.rb`) - Monitoring and metrics
76
+ - Benefits: Each module can be tested independently, easier maintenance, clear separation of concerns
77
+ - Pattern inspired by Waterdrop's modular client architecture
78
+
79
+ 2. **PGMQ::Connection** (`lib/pgmq/connection.rb`)
80
+ - Thread-safe connection pooling using `connection_pool` gem
81
+ - Supports multiple connection strategies:
82
+ - Connection strings: `postgres://user:pass@host/db`
83
+ - Hash parameters: `{ host:, port:, dbname:, user:, password: }`
84
+ - Callables (for Rails): `-> { ActiveRecord::Base.connection.raw_connection }`
85
+ - Auto-reconnect on connection failures (configurable)
86
+ - Connection health checks before use
87
+ - Note: Connection parameters are required - users should manage ENV variables themselves using `ENV.fetch`
88
+
89
+ 3. **PGMQ::Transaction** (`lib/pgmq/transaction.rb`)
90
+ - Low-level PostgreSQL transaction support (database primitive)
91
+ - Wraps PostgreSQL's native transactions (NOT a framework abstraction)
92
+ - Analogous to rdkafka-ruby providing Kafka transaction support
93
+ - Mixin providing `client.transaction do |txn|` support
94
+ - Enables atomic operations across multiple queues
95
+ - Rolls back automatically on errors
96
+
97
+ 4. **Models**
98
+ - **PGMQ::Message** - Represents queue messages with `msg_id`, `message` (raw JSONB), `read_ct`, `enqueued_at`, `vt`, `queue_name` (for multi-queue ops)
99
+ - **PGMQ::Metrics** - Queue metrics (length, age, total messages)
100
+ - **PGMQ::QueueMetadata** - Queue information (name, creation time)
101
+
102
+ ### Connection Pooling Details
103
+
104
+ - Default pool size: 5 connections
105
+ - Default timeout: 5 seconds
106
+ - Fiber-aware (works with Ruby 3.0+ Fiber Scheduler)
107
+ - Auto-reconnect enabled by default (can be disabled)
108
+ - Connection health verified before each use (if auto-reconnect enabled)
109
+
110
+ ### Error Hierarchy
111
+
112
+ ```
113
+ PGMQ::Errors::BaseError (StandardError)
114
+ ├── PGMQ::Errors::ConnectionError
115
+ ├── PGMQ::Errors::QueueNotFoundError
116
+ ├── PGMQ::Errors::MessageNotFoundError
117
+ ├── PGMQ::Errors::SerializationError
118
+ ├── PGMQ::Errors::ConfigurationError
119
+ └── PGMQ::Errors::InvalidQueueNameError
120
+ ```
121
+
122
+ ### Queue Name Validation
123
+
124
+ - Maximum 48 characters (PGMQ limitation for table prefixes)
125
+ - Must start with letter or underscore
126
+ - Only letters, digits, underscores allowed
127
+ - Case-sensitive
128
+ - Validated in `Client#validate_queue_name!`
129
+
130
+ ### Modular Architecture Pattern
131
+
132
+ The Client class follows Waterdrop's modular architecture pattern for better maintainability:
133
+
134
+ **Structure:**
135
+ - Small core `Client` class (~130 lines) that includes functional modules
136
+ - Each module focuses on a single domain area (queue management, producer, consumer, etc.)
137
+ - Modules access parent class helpers (`validate_queue_name!`, `with_connection`)
138
+ - Complete backward compatibility - no API changes
139
+
140
+ **Benefits:**
141
+ - **Testability**: Each module can be tested independently
142
+ - **Maintainability**: Smaller files, clearer boundaries (largest file ~210 lines)
143
+ - **Discoverability**: Logical grouping makes finding methods easier
144
+ - **Extensibility**: New modules can be added without bloating the core class
145
+
146
+ **Module Organization:**
147
+ 1. Transaction support (existing mixin)
148
+ 2. Queue lifecycle operations (create, drop, list)
149
+ 3. Message production (sending)
150
+ 4. Single-queue consumption (reading)
151
+ 5. Multi-queue operations (efficient polling across queues)
152
+ 6. Message lifecycle (pop, delete, archive, visibility timeout)
153
+ 7. Maintenance operations (purge, detach archive)
154
+ 8. Metrics and monitoring
155
+
156
+ All modules are automatically loaded via Zeitwerk.
157
+
158
+ ## Common Patterns
159
+
160
+ ### Client Initialization
161
+
162
+ ```ruby
163
+ # Connection string (preferred)
164
+ client = PGMQ::Client.new('postgres://localhost:5433/pgmq_test')
165
+
166
+ # Connection hash
167
+ client = PGMQ::Client.new(
168
+ host: 'localhost',
169
+ port: 5433,
170
+ dbname: 'pgmq_test',
171
+ user: 'postgres',
172
+ password: 'postgres'
173
+ )
174
+
175
+ # Connection hash using ENV variables (user manages ENV themselves)
176
+ client = PGMQ::Client.new(
177
+ host: ENV.fetch('PG_HOST', 'localhost'),
178
+ port: ENV.fetch('PG_PORT', 5432).to_i,
179
+ dbname: ENV.fetch('PG_DATABASE', 'pgmq'),
180
+ user: ENV.fetch('PG_USER', 'postgres'),
181
+ password: ENV.fetch('PG_PASSWORD', 'postgres')
182
+ )
183
+
184
+ # Rails integration (reuses Rails connection pool)
185
+ client = PGMQ::Client.new(-> { ActiveRecord::Base.connection.raw_connection })
186
+
187
+ # Custom pool configuration
188
+ client = PGMQ::Client.new(
189
+ 'postgres://localhost/db',
190
+ pool_size: 10,
191
+ pool_timeout: 10,
192
+ auto_reconnect: false
193
+ )
194
+ ```
195
+
196
+ ### Transaction Pattern
197
+
198
+ ```ruby
199
+ # Atomic operations across queues
200
+ client.transaction do |txn|
201
+ msg = txn.read('pending', vt: 30)
202
+ if msg
203
+ txn.produce('processed', msg.payload)
204
+ txn.delete('pending', msg.msg_id)
205
+ end
206
+ end
207
+ ```
208
+
209
+ ### Long Polling Pattern
210
+
211
+ ```ruby
212
+ # Efficient message consumption
213
+ loop do
214
+ msg = client.read_with_poll('orders',
215
+ vt: 30,
216
+ max_poll_seconds: 5,
217
+ poll_interval_ms: 100
218
+ )
219
+ break unless msg
220
+
221
+ process(msg)
222
+ client.delete('orders', msg.msg_id)
223
+ end
224
+ ```
225
+
226
+ ## Testing Guidelines
227
+
228
+ ### Test Structure
229
+
230
+ - **Unit tests** (`spec/unit/`) - Test classes in isolation, mock database
231
+ - **Integration tests** (`spec/integration/`) - Test full workflow with real PostgreSQL
232
+
233
+ ### Test Helpers
234
+
235
+ Located in `spec/support/database_helpers.rb`:
236
+ - Database cleanup between tests
237
+ - Connection helpers
238
+ - Common test utilities
239
+
240
+ ### Coverage Requirements
241
+
242
+ - Minimum overall coverage: 80%
243
+ - Minimum per-file coverage: 70%
244
+ - SimpleCov configured in `spec/spec_helper.rb`
245
+
246
+ ### Writing Tests
247
+
248
+ - Use descriptive test names
249
+ - Follow AAA pattern (Arrange, Act, Assert)
250
+ - Mock external dependencies in unit tests
251
+ - Use real database for integration tests
252
+ - Clean up queues in `after` blocks
253
+
254
+ ## Code Style
255
+
256
+ - Ruby 3.2+ syntax
257
+ - Frozen string literals (`# frozen_string_literal: true`)
258
+ - Max line length: 120 characters (except specs/gemspec)
259
+ - YARD documentation for public methods
260
+ - Single quotes for strings (unless interpolation needed)
261
+
262
+ ## CI/CD
263
+
264
+ GitHub Actions workflows in `.github/workflows/`:
265
+ - **ci.yml** - Runs RSpec on all Ruby versions (3.2, 3.3, 3.4, 3.5)
266
+ - **push.yml** - Additional checks on push
267
+
268
+ ## Dependencies
269
+
270
+ **Runtime:**
271
+ - `pg` (~> 1.5) - PostgreSQL adapter
272
+ - `connection_pool` (~> 2.4) - Thread-safe connection pooling
273
+
274
+ **Development:**
275
+ - `rspec` - Testing framework
276
+ - `simplecov` - Code coverage
277
+ - `pry` / `pry-byebug` - Debugging tools
278
+
279
+
280
+ ## Version Information
281
+
282
+ - Minimum Ruby: 3.2.0
283
+ - Supported PostgreSQL: 14-18 with PGMQ extension
284
+ - License: LGPL-3.0
285
+
286
+ ## Important Files
287
+
288
+ ### Core Library Structure
289
+ - `lib/pgmq/client.rb` - Main public API (~130 lines, includes all modules)
290
+ - `lib/pgmq/client/` - Client functional modules directory:
291
+ - `queue_management.rb` - Queue lifecycle operations (~100 lines)
292
+ - `producer.rb` - Message sending (~70 lines)
293
+ - `consumer.rb` - Single-queue reading (~140 lines)
294
+ - `multi_queue.rb` - Multi-queue operations (~200 lines)
295
+ - `message_lifecycle.rb` - Message state transitions (~210 lines)
296
+ - `maintenance.rb` - Queue maintenance (~30 lines)
297
+ - `metrics.rb` - Monitoring (~40 lines)
298
+ - `lib/pgmq/connection.rb` - Connection pooling and management
299
+ - `lib/pgmq/transaction.rb` - Transaction support
300
+ - `lib/pgmq/message.rb` - Message model (Data class)
301
+ - `lib/pgmq/metrics.rb` - Metrics model
302
+ - `lib/pgmq/queue_metadata.rb` - Queue metadata model
303
+
304
+ ### Documentation & Testing
305
+ - `spec/spec_helper.rb` - RSpec configuration + SimpleCov setup
306
+ - `spec/integration/` - Integration tests with real PostgreSQL
307
+ - `spec/unit/` - Unit tests for individual components
308
+ - `DEVELOPMENT.md` - Comprehensive development documentation
309
+ - `README.md` - User-facing documentation with all API examples
310
+ - `CLAUDE.md` - AI assistant guidance (this file)
data/Gemfile CHANGED
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source 'https://rubygems.org'
3
+ source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
6
 
7
7
  group :development, :test do
8
- gem 'rake'
9
- gem 'rspec'
10
- gem 'yard-lint'
8
+ gem "rake"
9
+ gem "rspec"
10
+ gem "async", "~> 2.6" # Fiber Scheduler for concurrent I/O testing
11
11
  end
12
12
 
13
13
  group :test do
14
- gem 'simplecov', require: false
14
+ gem "simplecov", require: false
15
15
  end
data/Gemfile.lint ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Documentation linting
6
+ gem "yard-lint"
7
+
8
+ # Code style (StandardRB via RuboCop)
9
+ gem "standard"
10
+ gem "standard-performance"
11
+ gem "rubocop-performance"
12
+ gem "rubocop-rspec"
13
+ gem "standard-rspec"
14
+ gem "rubocop-capybara"
15
+ gem "rubocop-factory_bot"
16
+ gem "rubocop-rspec_rails"