pgmq-ruby 0.5.0 → 0.6.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.
data/.yard-lint.yml DELETED
@@ -1,273 +0,0 @@
1
- # YARD-Lint Configuration
2
- # See https://github.com/mensfeld/yard-lint for documentation
3
-
4
- # Global settings for all validators
5
- AllValidators:
6
- YardOptions:
7
- - "--private"
8
- - "--protected"
9
- Exclude:
10
- - .git/**/*
11
- - vendor/**/*
12
- - node_modules/**/*
13
- - spec/**/*
14
- FailOnSeverity: convention
15
- RequiredCoverage: 100
16
-
17
- # Documentation validators
18
- Documentation/UndocumentedObjects:
19
- Description: Checks for classes, modules, and methods without documentation.
20
- Enabled: true
21
- Severity: error
22
- ExcludedMethods:
23
- - initialize/0
24
- - "/^_/"
25
-
26
- Documentation/UndocumentedMethodArguments:
27
- Description: Checks for method parameters without @param tags.
28
- Enabled: true
29
- Severity: error
30
-
31
- Documentation/UndocumentedBooleanMethods:
32
- Description: Checks that question mark methods document their boolean return.
33
- Enabled: true
34
- Severity: error
35
-
36
- Documentation/UndocumentedOptions:
37
- Description: Detects methods with options hash parameters but no @option tags.
38
- Enabled: true
39
- Severity: error
40
-
41
- Documentation/MarkdownSyntax:
42
- Description: Detects common markdown syntax errors in documentation.
43
- Enabled: true
44
- Severity: error
45
-
46
- Documentation/EmptyCommentLine:
47
- Description: Detects empty comment lines at the start or end of documentation blocks.
48
- Enabled: true
49
- Severity: convention
50
- EnabledPatterns:
51
- Leading: true
52
- Trailing: true
53
-
54
- Documentation/BlankLineBeforeDefinition:
55
- Description: Detects blank lines between YARD documentation and method definition.
56
- Enabled: true
57
- Severity: convention
58
- OrphanedSeverity: convention
59
- EnabledPatterns:
60
- SingleBlankLine: true
61
- OrphanedDocs: true
62
-
63
- # Tags validators
64
- Tags/Order:
65
- Description: Enforces consistent ordering of YARD tags.
66
- Enabled: true
67
- Severity: error
68
- EnforcedOrder:
69
- - param
70
- - option
71
- - return
72
- - raise
73
- - example
74
-
75
- Tags/InvalidTypes:
76
- Description: Validates type definitions in @param, @return, @option tags.
77
- Enabled: true
78
- Severity: error
79
- ValidatedTags:
80
- - param
81
- - option
82
- - return
83
-
84
- Tags/TypeSyntax:
85
- Description: Validates YARD type syntax using YARD parser.
86
- Enabled: true
87
- Severity: error
88
- ValidatedTags:
89
- - param
90
- - option
91
- - return
92
- - yieldreturn
93
-
94
- Tags/MeaninglessTag:
95
- Description: Detects @param/@option tags on classes, modules, or constants.
96
- Enabled: true
97
- Severity: error
98
- CheckedTags:
99
- - param
100
- - option
101
- InvalidObjectTypes:
102
- - class
103
- - module
104
- - constant
105
-
106
- Tags/CollectionType:
107
- Description: Validates Hash collection syntax consistency.
108
- Enabled: true
109
- Severity: error
110
- EnforcedStyle: long
111
- ValidatedTags:
112
- - param
113
- - option
114
- - return
115
- - yieldreturn
116
-
117
- Tags/TagTypePosition:
118
- Description: Validates type annotation position in tags.
119
- Enabled: true
120
- Severity: error
121
- CheckedTags:
122
- - param
123
- - option
124
- EnforcedStyle: type_after_name
125
-
126
- Tags/ApiTags:
127
- Description: Enforces @api tags on public objects.
128
- Enabled: false
129
- Severity: error
130
- AllowedApis:
131
- - public
132
- - private
133
- - internal
134
-
135
- Tags/OptionTags:
136
- Description: Requires @option tags for methods with options parameters.
137
- Enabled: true
138
- Severity: error
139
-
140
- Tags/ExampleSyntax:
141
- Description: Validates Ruby syntax in @example tags.
142
- Enabled: true
143
- Severity: warning
144
-
145
- Tags/RedundantParamDescription:
146
- Description: Detects meaningless parameter descriptions that add no value.
147
- Enabled: true
148
- Severity: convention
149
- CheckedTags:
150
- - param
151
- - option
152
- Articles:
153
- - The
154
- - the
155
- - A
156
- - a
157
- - An
158
- - an
159
- MaxRedundantWords: 6
160
- GenericTerms:
161
- - object
162
- - instance
163
- - value
164
- - data
165
- - item
166
- - element
167
- EnabledPatterns:
168
- ArticleParam: true
169
- PossessiveParam: true
170
- TypeRestatement: true
171
- ParamToVerb: true
172
- IdPattern: true
173
- DirectionalDate: true
174
- TypeGeneric: true
175
-
176
- Tags/InformalNotation:
177
- Description: Detects informal tag notation patterns like "Note:" instead of @note.
178
- Enabled: true
179
- Severity: warning
180
- CaseSensitive: false
181
- RequireStartOfLine: true
182
- Patterns:
183
- Note: "@note"
184
- Todo: "@todo"
185
- TODO: "@todo"
186
- FIXME: "@todo"
187
- See: "@see"
188
- See also: "@see"
189
- Warning: "@deprecated"
190
- Deprecated: "@deprecated"
191
- Author: "@author"
192
- Version: "@version"
193
- Since: "@since"
194
- Returns: "@return"
195
- Raises: "@raise"
196
- Example: "@example"
197
-
198
- Tags/NonAsciiType:
199
- Description: Detects non-ASCII characters in type annotations.
200
- Enabled: true
201
- Severity: warning
202
- ValidatedTags:
203
- - param
204
- - option
205
- - return
206
- - yieldreturn
207
- - yieldparam
208
-
209
- Tags/TagGroupSeparator:
210
- Description: Enforces blank line separators between different YARD tag groups.
211
- Enabled: false
212
- Severity: convention
213
- TagGroups:
214
- param:
215
- - param
216
- - option
217
- return:
218
- - return
219
- error:
220
- - raise
221
- - throws
222
- example:
223
- - example
224
- meta:
225
- - see
226
- - note
227
- - todo
228
- - deprecated
229
- - since
230
- - version
231
- - api
232
- yield:
233
- - yield
234
- - yieldparam
235
- - yieldreturn
236
- RequireAfterDescription: false
237
-
238
- # Warnings validators - catches YARD parser errors
239
- Warnings/UnknownTag:
240
- Description: Detects unknown YARD tags.
241
- Enabled: true
242
- Severity: error
243
-
244
- Warnings/UnknownDirective:
245
- Description: Detects unknown YARD directives.
246
- Enabled: true
247
- Severity: error
248
-
249
- Warnings/InvalidTagFormat:
250
- Description: Detects malformed tag syntax.
251
- Enabled: true
252
- Severity: error
253
-
254
- Warnings/InvalidDirectiveFormat:
255
- Description: Detects malformed directive syntax.
256
- Enabled: true
257
- Severity: error
258
-
259
- Warnings/DuplicatedParameterName:
260
- Description: Detects duplicate @param tags.
261
- Enabled: true
262
- Severity: error
263
-
264
- Warnings/UnknownParameterName:
265
- Description: Detects @param tags for non-existent parameters.
266
- Enabled: true
267
- Severity: error
268
-
269
- # Semantic validators
270
- Semantic/AbstractMethods:
271
- Description: Ensures @abstract methods do not have real implementations.
272
- Enabled: true
273
- Severity: error
data/CLAUDE.md DELETED
@@ -1,310 +0,0 @@
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 DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- gemspec
6
-
7
- group :development, :test do
8
- gem "rake"
9
- gem "rspec"
10
- gem "async", "~> 2.6" # Fiber Scheduler for concurrent I/O testing
11
- end
12
-
13
- group :test do
14
- gem "simplecov", require: false
15
- end
data/Gemfile.lint DELETED
@@ -1,16 +0,0 @@
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"