lepus 0.0.1.beta2 → 0.1.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/.github/workflows/linter.yml +21 -0
- data/.github/workflows/specs.yml +93 -13
- data/.gitignore +2 -0
- data/.rubocop.yml +10 -0
- data/.tool-versions +1 -1
- data/Gemfile +7 -0
- data/Gemfile.lock +36 -9
- data/Makefile +19 -0
- data/README.md +562 -7
- data/bin/setup +5 -2
- data/config.ru +14 -0
- data/docker-compose.yml +5 -3
- data/docs/README.md +80 -0
- data/docs/cli.md +108 -0
- data/docs/configuration.md +171 -0
- data/docs/consumers.md +168 -0
- data/docs/getting-started.md +136 -0
- data/docs/images/lepus-web.png +0 -0
- data/docs/middleware.md +240 -0
- data/docs/producers.md +173 -0
- data/docs/prometheus.md +112 -0
- data/docs/rails.md +161 -0
- data/docs/supervisor.md +112 -0
- data/docs/testing.md +141 -0
- data/docs/web.md +85 -0
- data/examples/grafana-dashboard.json +450 -0
- data/gemfiles/Gemfile.rails-5.2 +7 -0
- data/gemfiles/{rails52.gemfile.lock → Gemfile.rails-5.2.lock} +102 -69
- data/gemfiles/Gemfile.rails-6.1 +7 -0
- data/gemfiles/{rails61.gemfile.lock → Gemfile.rails-6.1.lock} +113 -79
- data/gemfiles/{rails52.gemfile → Gemfile.rails-7.2} +1 -1
- data/gemfiles/Gemfile.rails-7.2.lock +321 -0
- data/gemfiles/{rails61.gemfile → Gemfile.rails-8.0} +1 -1
- data/gemfiles/Gemfile.rails-8.0.lock +322 -0
- data/lepus.gemspec +7 -1
- data/lib/lepus/cli.rb +35 -4
- data/lib/lepus/configuration.rb +107 -0
- data/lib/lepus/connection_pool.rb +135 -0
- data/lib/lepus/consumer.rb +59 -41
- data/lib/lepus/consumers/config.rb +183 -0
- data/lib/lepus/consumers/handler.rb +56 -0
- data/lib/lepus/consumers/middleware_chain.rb +22 -0
- data/lib/lepus/consumers/middlewares/exception_logger.rb +27 -0
- data/lib/lepus/consumers/middlewares/honeybadger.rb +33 -0
- data/lib/lepus/consumers/middlewares/json.rb +37 -0
- data/lib/lepus/consumers/middlewares/max_retry.rb +83 -0
- data/lib/lepus/consumers/middlewares/unique.rb +65 -0
- data/lib/lepus/consumers/stats.rb +70 -0
- data/lib/lepus/consumers/stats_registry.rb +29 -0
- data/lib/lepus/consumers/worker.rb +141 -0
- data/lib/lepus/consumers/worker_factory.rb +124 -0
- data/lib/lepus/consumers.rb +6 -0
- data/lib/lepus/message/delivery_info.rb +72 -0
- data/lib/lepus/message/metadata.rb +99 -0
- data/lib/lepus/message.rb +88 -5
- data/lib/lepus/middleware_chain.rb +83 -0
- data/lib/lepus/primitive/hash.rb +29 -0
- data/lib/lepus/process.rb +24 -24
- data/lib/lepus/process_registry/backend.rb +49 -0
- data/lib/lepus/process_registry/file_backend.rb +108 -0
- data/lib/lepus/process_registry/message_builder.rb +72 -0
- data/lib/lepus/process_registry/rabbitmq_backend.rb +153 -0
- data/lib/lepus/process_registry.rb +56 -23
- data/lib/lepus/processes/base.rb +0 -5
- data/lib/lepus/processes/callbacks.rb +3 -0
- data/lib/lepus/processes/interruptible.rb +4 -8
- data/lib/lepus/processes/procline.rb +1 -1
- data/lib/lepus/processes/registrable.rb +1 -1
- data/lib/lepus/processes/runnable.rb +1 -1
- data/lib/lepus/processes.rb +15 -0
- data/lib/lepus/producer.rb +141 -30
- data/lib/lepus/producers/config.rb +46 -0
- data/lib/lepus/producers/definition.rb +48 -0
- data/lib/lepus/producers/hooks.rb +170 -0
- data/lib/lepus/producers/middleware_chain.rb +22 -0
- data/lib/lepus/producers/middlewares/correlation_id.rb +37 -0
- data/lib/lepus/producers/middlewares/header.rb +47 -0
- data/lib/lepus/producers/middlewares/instrumentation.rb +30 -0
- data/lib/lepus/producers/middlewares/json.rb +47 -0
- data/lib/lepus/producers/middlewares/unique.rb +67 -0
- data/lib/lepus/producers.rb +7 -0
- data/lib/lepus/prometheus/collector.rb +149 -0
- data/lib/lepus/prometheus/instrumentation.rb +168 -0
- data/lib/lepus/prometheus.rb +48 -0
- data/lib/lepus/publisher.rb +67 -0
- data/lib/lepus/supervisor/children_pipes.rb +25 -0
- data/lib/lepus/supervisor/lifecycle_hooks.rb +50 -0
- data/lib/lepus/supervisor/pidfiled.rb +1 -1
- data/lib/lepus/supervisor/registry_cleaner.rb +22 -0
- data/lib/lepus/supervisor.rb +129 -25
- data/lib/lepus/testing/exchange.rb +95 -0
- data/lib/lepus/testing/message_builder.rb +177 -0
- data/lib/lepus/testing/rspec_matchers.rb +258 -0
- data/lib/lepus/testing.rb +210 -0
- data/lib/lepus/unique.rb +18 -0
- data/lib/lepus/version.rb +1 -1
- data/lib/lepus/web/aggregator.rb +154 -0
- data/lib/lepus/web/api.rb +132 -0
- data/lib/lepus/web/app.rb +37 -0
- data/lib/lepus/web/management_api.rb +192 -0
- data/lib/lepus/web/respond_with.rb +28 -0
- data/lib/lepus/web.rb +238 -0
- data/lib/lepus.rb +39 -28
- data/test_offline.html +189 -0
- data/web/assets/css/styles.css +635 -0
- data/web/assets/js/app.js +6 -0
- data/web/assets/js/bootstrap.js +20 -0
- data/web/assets/js/controllers/connection_controller.js +44 -0
- data/web/assets/js/controllers/dashboard_controller.js +499 -0
- data/web/assets/js/controllers/queue_controller.js +17 -0
- data/web/assets/js/controllers/theme_controller.js +31 -0
- data/web/assets/js/offline-manager.js +233 -0
- data/web/assets/js/service-worker-manager.js +65 -0
- data/web/index.html +159 -0
- data/web/sw.js +144 -0
- metadata +177 -18
- data/lib/lepus/consumer_config.rb +0 -149
- data/lib/lepus/consumer_wrapper.rb +0 -46
- data/lib/lepus/lifecycle_hooks.rb +0 -49
- data/lib/lepus/middlewares/honeybadger.rb +0 -23
- data/lib/lepus/middlewares/json.rb +0 -35
- data/lib/lepus/middlewares/max_retry.rb +0 -57
- data/lib/lepus/processes/consumer.rb +0 -113
- data/lib/lepus/supervisor/config.rb +0 -45
data/test_offline.html
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Lepus Offline Test</title>
|
|
7
|
+
<style>
|
|
8
|
+
body { font-family: system-ui; padding: 20px; }
|
|
9
|
+
.test-section { margin: 20px 0; padding: 15px; border: 1px solid #ccc; border-radius: 5px; }
|
|
10
|
+
.success { background: #d4edda; border-color: #c3e6cb; }
|
|
11
|
+
.error { background: #f8d7da; border-color: #f5c6cb; }
|
|
12
|
+
.info { background: #d1ecf1; border-color: #bee5eb; }
|
|
13
|
+
button { padding: 10px 15px; margin: 5px; cursor: pointer; }
|
|
14
|
+
</style>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
<h1>Lepus Offline Support Test</h1>
|
|
18
|
+
|
|
19
|
+
<div class="test-section info">
|
|
20
|
+
<h3>Current Status</h3>
|
|
21
|
+
<p>Online: <span id="online-status">Checking...</span></p>
|
|
22
|
+
<p>Service Worker: <span id="sw-status">Checking...</span></p>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="test-section">
|
|
26
|
+
<h3>Test Controls</h3>
|
|
27
|
+
<button onclick="simulateOffline()">Simulate Offline</button>
|
|
28
|
+
<button onclick="simulateOnline()">Simulate Online</button>
|
|
29
|
+
<button onclick="testExternalDependencies()">Test External Dependencies</button>
|
|
30
|
+
<button onclick="testServiceWorker()">Test Service Worker</button>
|
|
31
|
+
<button onclick="testOfflineModules()">Test Offline Modules</button>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div class="test-section">
|
|
35
|
+
<h3>Test Results</h3>
|
|
36
|
+
<div id="test-results"></div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<script>
|
|
40
|
+
// Test offline functionality
|
|
41
|
+
function updateStatus() {
|
|
42
|
+
document.getElementById('online-status').textContent = navigator.onLine ? 'Yes' : 'No';
|
|
43
|
+
document.getElementById('online-status').style.color = navigator.onLine ? 'green' : 'red';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function addResult(message, type = 'info') {
|
|
47
|
+
const results = document.getElementById('test-results');
|
|
48
|
+
const div = document.createElement('div');
|
|
49
|
+
div.className = `test-section ${type}`;
|
|
50
|
+
div.innerHTML = `<p>${new Date().toLocaleTimeString()}: ${message}</p>`;
|
|
51
|
+
results.appendChild(div);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function simulateOffline() {
|
|
55
|
+
Object.defineProperty(navigator, 'onLine', {
|
|
56
|
+
writable: true,
|
|
57
|
+
value: false
|
|
58
|
+
});
|
|
59
|
+
window.dispatchEvent(new Event('offline'));
|
|
60
|
+
updateStatus();
|
|
61
|
+
addResult('Simulated offline state', 'info');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function simulateOnline() {
|
|
65
|
+
Object.defineProperty(navigator, 'onLine', {
|
|
66
|
+
writable: true,
|
|
67
|
+
value: true
|
|
68
|
+
});
|
|
69
|
+
window.dispatchEvent(new Event('online'));
|
|
70
|
+
updateStatus();
|
|
71
|
+
addResult('Simulated online state', 'success');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function testExternalDependencies() {
|
|
75
|
+
addResult('Testing external dependencies...', 'info');
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
// Test Stimulus CDN
|
|
79
|
+
const stimulusResponse = await fetch('https://unpkg.com/@hotwired/stimulus@3.2.2/dist/stimulus.umd.js');
|
|
80
|
+
if (stimulusResponse.ok) {
|
|
81
|
+
addResult('✓ Stimulus CDN accessible', 'success');
|
|
82
|
+
} else {
|
|
83
|
+
addResult('✗ Stimulus CDN not accessible', 'error');
|
|
84
|
+
}
|
|
85
|
+
} catch (error) {
|
|
86
|
+
addResult('✗ Stimulus CDN failed: ' + error.message, 'error');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
// Test Chart.js CDN
|
|
91
|
+
const chartResponse = await fetch('https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js');
|
|
92
|
+
if (chartResponse.ok) {
|
|
93
|
+
addResult('✓ Chart.js CDN accessible', 'success');
|
|
94
|
+
} else {
|
|
95
|
+
addResult('✗ Chart.js CDN not accessible', 'error');
|
|
96
|
+
}
|
|
97
|
+
} catch (error) {
|
|
98
|
+
addResult('✗ Chart.js CDN failed: ' + error.message, 'error');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function testServiceWorker() {
|
|
103
|
+
if ('serviceWorker' in navigator) {
|
|
104
|
+
navigator.serviceWorker.register('/sw.js')
|
|
105
|
+
.then(registration => {
|
|
106
|
+
addResult('✓ Service Worker registered successfully', 'success');
|
|
107
|
+
return navigator.serviceWorker.ready;
|
|
108
|
+
})
|
|
109
|
+
.then(registration => {
|
|
110
|
+
addResult('✓ Service Worker ready', 'success');
|
|
111
|
+
document.getElementById('sw-status').textContent = 'Active';
|
|
112
|
+
document.getElementById('sw-status').style.color = 'green';
|
|
113
|
+
})
|
|
114
|
+
.catch(error => {
|
|
115
|
+
addResult('✗ Service Worker failed: ' + error.message, 'error');
|
|
116
|
+
document.getElementById('sw-status').textContent = 'Failed';
|
|
117
|
+
document.getElementById('sw-status').style.color = 'red';
|
|
118
|
+
});
|
|
119
|
+
} else {
|
|
120
|
+
addResult('✗ Service Worker not supported', 'error');
|
|
121
|
+
document.getElementById('sw-status').textContent = 'Not Supported';
|
|
122
|
+
document.getElementById('sw-status').style.color = 'red';
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function testOfflineModules() {
|
|
127
|
+
addResult('Testing offline modules...', 'info');
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
// Test offline-manager.js
|
|
131
|
+
const offlineResponse = await fetch('/assets/js/offline-manager.js');
|
|
132
|
+
if (offlineResponse.ok) {
|
|
133
|
+
addResult('✓ offline-manager.js accessible', 'success');
|
|
134
|
+
} else {
|
|
135
|
+
addResult('✗ offline-manager.js not accessible', 'error');
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
addResult('✗ offline-manager.js failed: ' + error.message, 'error');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
// Test service-worker-manager.js
|
|
143
|
+
const swResponse = await fetch('/assets/js/service-worker-manager.js');
|
|
144
|
+
if (swResponse.ok) {
|
|
145
|
+
addResult('✓ service-worker-manager.js accessible', 'success');
|
|
146
|
+
} else {
|
|
147
|
+
addResult('✗ service-worker-manager.js not accessible', 'error');
|
|
148
|
+
}
|
|
149
|
+
} catch (error) {
|
|
150
|
+
addResult('✗ service-worker-manager.js failed: ' + error.message, 'error');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Test if modules are loaded in window
|
|
154
|
+
if (window.OfflineManager) {
|
|
155
|
+
addResult('✓ OfflineManager class available', 'success');
|
|
156
|
+
} else {
|
|
157
|
+
addResult('✗ OfflineManager class not available', 'error');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (window.ServiceWorkerManager) {
|
|
161
|
+
addResult('✓ ServiceWorkerManager class available', 'success');
|
|
162
|
+
} else {
|
|
163
|
+
addResult('✗ ServiceWorkerManager class not available', 'error');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Initialize
|
|
168
|
+
updateStatus();
|
|
169
|
+
|
|
170
|
+
// Listen for online/offline events
|
|
171
|
+
window.addEventListener('online', () => {
|
|
172
|
+
updateStatus();
|
|
173
|
+
addResult('Browser went online', 'success');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
window.addEventListener('offline', () => {
|
|
177
|
+
updateStatus();
|
|
178
|
+
addResult('Browser went offline', 'error');
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Auto-test on load
|
|
182
|
+
setTimeout(() => {
|
|
183
|
+
testExternalDependencies();
|
|
184
|
+
testServiceWorker();
|
|
185
|
+
testOfflineModules();
|
|
186
|
+
}, 1000);
|
|
187
|
+
</script>
|
|
188
|
+
</body>
|
|
189
|
+
</html>
|