patient_http-solid_queue 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a3dff2ec8890085fac33d90459fae8756ba79fbf357579ac1cacb71a49f7e8fe
4
+ data.tar.gz: 8664f9bad61dc7db22fd7e3908ea705b094703863e9d13598f0f787e91e6d1f9
5
+ SHA512:
6
+ metadata.gz: 106fc849d06ab190c8d691cf4f99066bd7fcc6c3cc0be20da1a95a43fbc73e4ff7cb1517a555bd008c4a55113394096985eb58835c04a579be098b371f2fdb14
7
+ data.tar.gz: 502cd86c858693f6c70edc88a97e2cae08e9a6f85712dc7f2fb06d5066124ae679351e7b685fa4fba4a4c0da97020f096c3673ca451aa768b329d2c7b01d61a3
data/ARCHITECTURE.md ADDED
@@ -0,0 +1,119 @@
1
+ # Architecture
2
+
3
+ ## Overview
4
+
5
+ PatientHttp::SolidQueue provides a Solid Queue integration layer for the [patient_http](https://github.com/bdurand/patient_http) gem, enabling long-running HTTP requests to be offloaded from worker execution to a dedicated async I/O processor. This integration uses Active Job for request enqueueing and callback invocation, while leveraging patient_http's Fiber-based concurrency to handle many concurrent HTTP requests without blocking worker threads.
6
+
7
+ ## Key Design Principles
8
+
9
+ 1. **Non-blocking workers**: Jobs enqueue HTTP requests and quickly return so worker capacity remains available
10
+ 2. **Singleton processor per process**: One async I/O processor per worker process handles request concurrency
11
+ 3. **Callback service pattern**: HTTP results are delivered to callback services via `on_complete` and `on_error`
12
+ 4. **Lifecycle integration**: Processor lifecycle is tied to Solid Queue worker start/stop hooks
13
+ 5. **Active Job-native task handling**: Request execution, callback jobs, and retries use Active Job semantics
14
+
15
+ ## Core Components
16
+
17
+ ### PatientHttp::Processor (from patient_http)
18
+ A dedicated processor thread that runs an async fiber reactor and manages concurrent HTTP execution.
19
+
20
+ ### PatientHttp::SolidQueue::RequestJob
21
+ Active Job entry point for async requests. It:
22
+ - receives serialized request payloads
23
+ - decrypts and loads request data
24
+ - submits the request to `RequestExecutor`
25
+
26
+ ### PatientHttp::SolidQueue::TaskHandler
27
+ Implements patient_http task handling for Active Job integration. It:
28
+ - enqueues `CallbackJob` on completion/error
29
+ - retries original jobs via `ActiveJob::Base.deserialize(...).enqueue`
30
+ - stores large payloads using external storage when configured
31
+
32
+ ### PatientHttp::SolidQueue::CallbackJob
33
+ Active Job that resolves the callback class and invokes:
34
+ - `on_complete(response)` for successful requests
35
+ - `on_error(error)` for request errors
36
+
37
+ ### PatientHttp::SolidQueue::LifecycleHooks
38
+ Registers hooks to automatically:
39
+ - start processor on `SolidQueue.on_worker_start`
40
+ - stop processor on `SolidQueue.on_worker_stop`
41
+
42
+ ### PatientHttp::SolidQueue::ProcessorObserver
43
+ Observes processor task lifecycle and updates task monitor records.
44
+
45
+ ### PatientHttp::SolidQueue::TaskMonitor
46
+ Tracks in-flight requests in database tables and performs orphan recovery. It:
47
+ - records request heartbeats
48
+ - tracks active processes
49
+ - re-enqueues orphaned requests from stale processes
50
+
51
+ ### PatientHttp::SolidQueue::TaskMonitorThread
52
+ Background thread that periodically:
53
+ - updates in-flight heartbeats
54
+ - pings process registration
55
+ - runs orphan cleanup under a distributed DB lock
56
+
57
+ ### Configuration
58
+ `PatientHttp::SolidQueue::Configuration` wraps patient_http configuration and adds Solid Queue-specific options such as:
59
+ - `queue_name`
60
+ - `heartbeat_interval`
61
+ - `orphan_threshold`
62
+ - `payload_store_threshold`
63
+
64
+ ## Request Lifecycle
65
+
66
+ 1. Application code calls `PatientHttp.get/post/put/patch/delete` (which delegates to the registered Solid Queue handler) or `PatientHttp::SolidQueue.execute` directly.
67
+ 2. `RequestJob` is enqueued with serialized request data and callback metadata.
68
+ 3. `RequestJob` decrypts/deserializes and calls `RequestExecutor.execute`.
69
+ 4. `RequestExecutor` creates an async task and enqueues it on the processor.
70
+ 5. Processor executes HTTP request asynchronously.
71
+ 6. `TaskHandler` enqueues `CallbackJob` with serialized response/error.
72
+ 7. `CallbackJob` invokes the callback service method.
73
+
74
+ ## Process Model
75
+
76
+ Each worker process runs:
77
+ - worker threads for regular Active Job execution
78
+ - one async HTTP processor thread
79
+ - one task monitor thread for heartbeat and orphan recovery
80
+
81
+ ## State Management
82
+
83
+ Processor lifecycle states are managed by patient_http and exposed via:
84
+ - `PatientHttp::SolidQueue.running?`
85
+ - `PatientHttp::SolidQueue.draining?`
86
+ - `PatientHttp::SolidQueue.stopping?`
87
+ - `PatientHttp::SolidQueue.stopped?`
88
+
89
+ On shutdown, the processor waits up to `shutdown_timeout` for in-flight requests before interrupting remaining tasks.
90
+
91
+ ## Crash Recovery
92
+
93
+ Crash recovery is database-backed:
94
+
95
+ - In-flight requests are stored in `patient_http_solid_queue_inflight_requests`
96
+ - Active processes are tracked in `patient_http_solid_queue_processes`
97
+ - Distributed GC/orphan cleanup coordination uses `patient_http_solid_queue_gc_locks`
98
+
99
+ Recovery flow:
100
+ 1. A request is registered with process ID + heartbeat timestamp
101
+ 2. Heartbeats are updated while request remains in-flight
102
+ 3. If a process stops heartbeating past `orphan_threshold`, another process can reclaim the request
103
+ 4. The original Active Job is re-enqueued with executions reset
104
+
105
+ ## Monitoring Hooks
106
+
107
+ Instrumentation hooks are available globally:
108
+ - `PatientHttp::SolidQueue.after_completion { |response| ... }`
109
+ - `PatientHttp::SolidQueue.after_error { |error| ... }`
110
+
111
+ These callbacks support metrics pipelines (StatsD, Prometheus adapters, etc.) and error reporting integrations.
112
+
113
+ ## Testing Behavior
114
+
115
+ In test mode (`PatientHttp.testing?`), request execution runs synchronously to make specs deterministic while keeping the same public API.
116
+
117
+ ## Further Reading
118
+
119
+ - [README](README.md)
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## 1.0.0
8
+
9
+ ### Added
10
+
11
+ - Dedicated async HTTP processor integration for Solid Queue to avoid blocking worker threads during in-flight requests.
12
+ - `PatientHttp::SolidQueue` API with convenience methods for common HTTP verbs (`get`, `post`, `put`, `patch`, and `delete`).
13
+ - Callback-based completion and error handling via `on_complete` and `on_error`, executed through Active Job via `PatientHttp::SolidQueue::CallbackJob`.
14
+ - Support for callback context via `callback_args`, available from response and error objects.
15
+ - Automatic processor lifecycle integration with `SolidQueue.on_worker_start` and `SolidQueue.on_worker_stop` hooks.
16
+ - Database-backed in-flight request tracking with heartbeat updates, orphan detection, and automatic re-enqueue of interrupted requests.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2026 Brian Durand
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.