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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/README.md +7 -1
- data/lib/pgmq/connection.rb +24 -1
- data/lib/pgmq/version.rb +1 -1
- data/pgmq-ruby.gemspec +2 -2
- metadata +3 -20
- data/.github/workflows/ci.yml +0 -183
- data/.github/workflows/push.yml +0 -35
- data/.gitignore +0 -67
- data/.rspec +0 -2
- data/.rubocop.yml +0 -66
- data/.ruby-version +0 -1
- data/.yard-lint.yml +0 -273
- data/CLAUDE.md +0 -310
- data/Gemfile +0 -15
- data/Gemfile.lint +0 -16
- data/Gemfile.lint.lock +0 -120
- data/Gemfile.lock +0 -79
- data/Rakefile +0 -73
- data/docker-compose.yml +0 -22
- data/package-lock.json +0 -331
- data/package.json +0 -9
- data/renovate.json +0 -30
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"
|