passive_queue 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 +7 -0
- data/CHANGELOG.md +88 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +35 -0
- data/LICENSE +21 -0
- data/README.md +1 -0
- data/bin/be +9 -0
- data/html/landing.html +1237 -0
- data/html/logo-dark.svg +166 -0
- data/html/logo.svg +166 -0
- data/lib/active_job/queue_adapters/passive_queue_adapter.rb +16 -0
- data/lib/passive_queue/adapter.rb +42 -0
- data/lib/passive_queue/cli.rb +139 -0
- data/lib/passive_queue/configuration.rb +23 -0
- data/lib/passive_queue/engine.rb +26 -0
- data/lib/passive_queue/railtie.rb +18 -0
- data/lib/passive_queue/version.rb +7 -0
- data/lib/passive_queue/web.rb +623 -0
- data/lib/passive_queue.rb +52 -0
- metadata +63 -0
data/html/landing.html
ADDED
@@ -0,0 +1,1237 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en" data-theme="light">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>Passive Queue - The Art of Non-Execution</title>
|
7
|
+
|
8
|
+
<script>
|
9
|
+
(function() {
|
10
|
+
// Get saved theme or default to auto
|
11
|
+
const savedTheme = localStorage.getItem('theme');
|
12
|
+
const themeToApply = savedTheme !== null ? savedTheme : 'auto';
|
13
|
+
|
14
|
+
function getSystemTheme() {
|
15
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
16
|
+
}
|
17
|
+
|
18
|
+
let actualTheme;
|
19
|
+
if (themeToApply === 'auto') {
|
20
|
+
actualTheme = getSystemTheme();
|
21
|
+
} else {
|
22
|
+
actualTheme = themeToApply;
|
23
|
+
}
|
24
|
+
|
25
|
+
// Apply theme immediately to prevent flash
|
26
|
+
document.documentElement.setAttribute('data-theme', actualTheme);
|
27
|
+
|
28
|
+
// Store current preference for later use
|
29
|
+
window.currentThemePreference = themeToApply;
|
30
|
+
})();
|
31
|
+
</script>
|
32
|
+
|
33
|
+
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
|
34
|
+
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
|
35
|
+
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
36
|
+
|
37
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css">
|
38
|
+
|
39
|
+
<!-- Highlight.js JavaScript -->
|
40
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
41
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/ruby.min.js"></script>
|
42
|
+
|
43
|
+
|
44
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
45
|
+
<style>
|
46
|
+
body { font-family: 'Inter', sans-serif; }
|
47
|
+
|
48
|
+
/* Light mode gradients and shadows (default) */
|
49
|
+
.zen-gradient {
|
50
|
+
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
|
51
|
+
}
|
52
|
+
.peaceful-shadow {
|
53
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
|
54
|
+
}
|
55
|
+
|
56
|
+
/* Dark mode variations */
|
57
|
+
[data-theme="dark"] .zen-gradient {
|
58
|
+
background: linear-gradient(135deg, #1f2937 0%, #111827 100%);
|
59
|
+
}
|
60
|
+
[data-theme="dark"] .peaceful-shadow {
|
61
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
62
|
+
}
|
63
|
+
|
64
|
+
/* Animations remain the same */
|
65
|
+
.loading-dots::after {
|
66
|
+
content: '';
|
67
|
+
animation: dots 2s infinite;
|
68
|
+
}
|
69
|
+
@keyframes dots {
|
70
|
+
0%, 20% { content: '.'; }
|
71
|
+
40% { content: '..'; }
|
72
|
+
60% { content: '...'; }
|
73
|
+
80%, 100% { content: ''; }
|
74
|
+
}
|
75
|
+
.float { animation: float 6s ease-in-out infinite; }
|
76
|
+
@keyframes float {
|
77
|
+
0%, 100% { transform: translateY(0px); }
|
78
|
+
50% { transform: translateY(-10px); }
|
79
|
+
}
|
80
|
+
|
81
|
+
/* Theme toggle button styles */
|
82
|
+
.theme-toggle {
|
83
|
+
display: none;
|
84
|
+
width: 48px;
|
85
|
+
height: 24px;
|
86
|
+
background: var(--fallback-b2,oklch(var(--b2)));
|
87
|
+
border-radius: 12px;
|
88
|
+
border: 2px solid var(--fallback-bc,oklch(var(--bc)/0.2));
|
89
|
+
cursor: pointer;
|
90
|
+
position: relative;
|
91
|
+
transition: all 0.3s ease;
|
92
|
+
}
|
93
|
+
|
94
|
+
.theme-toggle::before {
|
95
|
+
content: '';
|
96
|
+
position: absolute;
|
97
|
+
top: 50%;
|
98
|
+
left: 2px;
|
99
|
+
transform: translateY(-50%);
|
100
|
+
font-size: 14px;
|
101
|
+
transition: all 0.3s ease;
|
102
|
+
}
|
103
|
+
|
104
|
+
[data-theme="dark"] .theme-toggle::before {
|
105
|
+
content: '';
|
106
|
+
left: 22px;
|
107
|
+
}
|
108
|
+
|
109
|
+
.theme-toggle::after {
|
110
|
+
content: '';
|
111
|
+
position: absolute;
|
112
|
+
top: 2px;
|
113
|
+
left: 2px;
|
114
|
+
width: 16px;
|
115
|
+
height: 16px;
|
116
|
+
background: var(--fallback-bc,oklch(var(--bc)));
|
117
|
+
border-radius: 50%;
|
118
|
+
transition: all 0.3s ease;
|
119
|
+
}
|
120
|
+
|
121
|
+
[data-theme="dark"] .theme-toggle::after {
|
122
|
+
transform: translateX(20px);
|
123
|
+
}
|
124
|
+
|
125
|
+
/* Code container dark mode support */
|
126
|
+
.code-container {
|
127
|
+
background: #1f2937;
|
128
|
+
border-radius: 0.5rem;
|
129
|
+
padding: 1.5rem;
|
130
|
+
overflow-x: auto;
|
131
|
+
}
|
132
|
+
|
133
|
+
[data-theme="dark"] .code-container {
|
134
|
+
background: #0f172a;
|
135
|
+
border: 1px solid #334155;
|
136
|
+
}
|
137
|
+
</style>
|
138
|
+
|
139
|
+
<style>
|
140
|
+
|
141
|
+
|
142
|
+
/* Custom styling for the code block */
|
143
|
+
.code-container {
|
144
|
+
background: #1f2937;
|
145
|
+
border-radius: 0.5rem;
|
146
|
+
padding: 1.5rem;
|
147
|
+
overflow-x: auto;
|
148
|
+
}
|
149
|
+
|
150
|
+
.code-container pre {
|
151
|
+
margin: 0;
|
152
|
+
padding: 0;
|
153
|
+
background: transparent;
|
154
|
+
}
|
155
|
+
|
156
|
+
.code-container code {
|
157
|
+
background: transparent;
|
158
|
+
padding: 0;
|
159
|
+
font-family: 'Courier New', monospace;
|
160
|
+
font-size: 0.875rem;
|
161
|
+
line-height: 1.5;
|
162
|
+
}
|
163
|
+
|
164
|
+
/* Highlight.js theme customization for dark background */
|
165
|
+
.hljs {
|
166
|
+
background: transparent !important;
|
167
|
+
color: #e5e7eb;
|
168
|
+
}
|
169
|
+
|
170
|
+
.hljs-comment {
|
171
|
+
color: #6b7280;
|
172
|
+
font-style: italic;
|
173
|
+
}
|
174
|
+
|
175
|
+
.hljs-string {
|
176
|
+
color: #10b981;
|
177
|
+
}
|
178
|
+
|
179
|
+
.hljs-keyword {
|
180
|
+
color: #8b5cf6;
|
181
|
+
}
|
182
|
+
|
183
|
+
.hljs-title {
|
184
|
+
color: #3b82f6;
|
185
|
+
}
|
186
|
+
|
187
|
+
.hljs-variable {
|
188
|
+
color: #ef4444;
|
189
|
+
}
|
190
|
+
|
191
|
+
.hljs-symbol {
|
192
|
+
color: #f59e0b;
|
193
|
+
}
|
194
|
+
</style>
|
195
|
+
</head>
|
196
|
+
<body class="zen-gradient min-h-screen">
|
197
|
+
<!-- Navigation -->
|
198
|
+
<div class="navbar bg-base-100/80 backdrop-blur-sm sticky top-0 z-50 peaceful-shadow">
|
199
|
+
<div class="navbar-start">
|
200
|
+
<div class="dropdown">
|
201
|
+
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
202
|
+
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
203
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16"></path>
|
204
|
+
</svg>
|
205
|
+
</div>
|
206
|
+
<ul tabindex="0" class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
|
207
|
+
<li><a href="#features">Features</a></li>
|
208
|
+
<li><a href="#pricing">Pricing</a></li>
|
209
|
+
<li><a href="#docs">Docs</a></li>
|
210
|
+
<li><a href="#demo">Demo</a></li>
|
211
|
+
</ul>
|
212
|
+
</div>
|
213
|
+
<a class="btn btn-ghost text-xl font-light" href="https://passivequeue.pro">
|
214
|
+
|
215
|
+
|
216
|
+
<img src="logo.svg" alt="Passive Queue Logo"
|
217
|
+
class="w-16 h-16 mx-auto mb-0 block mr-2 logo-light" id="" style="width: 28px; height: 28px;">
|
218
|
+
<!-- Dark mode logo -->
|
219
|
+
<img src="logo-dark.svg" alt="Passive Queue Logo"
|
220
|
+
class="w-16 h-16 mx-auto mb-0 mr-2 hidden logo-dark" id="" style="width: 28px; height: 28px;">
|
221
|
+
|
222
|
+
Passive Queue
|
223
|
+
</a>
|
224
|
+
</div>
|
225
|
+
<div class="navbar-center hidden lg:flex">
|
226
|
+
<ul class="menu menu-horizontal px-1 text-lg">
|
227
|
+
<li><a href="#features" class="font-light">Features</a></li>
|
228
|
+
<li><a href="#pricing" class="font-light">Pricing</a></li>
|
229
|
+
<li><a href="#docs" class="font-light">Documentation</a></li>
|
230
|
+
<li><a href="#demo" class="font-light">Demo</a></li>
|
231
|
+
</ul>
|
232
|
+
</div>
|
233
|
+
|
234
|
+
<div class="navbar-end">
|
235
|
+
<!-- Theme Toggle -->
|
236
|
+
<div class="flex items-center gap-2 mr-4">
|
237
|
+
<button class="theme-toggle" onclick="toggleTheme()" aria-label="Toggle theme"></button>
|
238
|
+
<div class="dropdown dropdown-end">
|
239
|
+
<div tabindex="0" role="button" class="btn btn-ghost btn-sm">
|
240
|
+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
241
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path>
|
242
|
+
</svg>
|
243
|
+
</div>
|
244
|
+
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52">
|
245
|
+
<li><a onclick="setTheme('light')">☀️ Light Mode</a></li>
|
246
|
+
<li><a onclick="setTheme('dark')">🌙 Dark Mode</a></li>
|
247
|
+
<li><a onclick="setTheme('auto')">🔄 Auto (System)</a></li>
|
248
|
+
</ul>
|
249
|
+
</div>
|
250
|
+
</div>
|
251
|
+
<!-- Your existing GitHub link -->
|
252
|
+
<a href="https://github.com/mensfeld/passive_queue" class="btn btn-ghost btn-sm">
|
253
|
+
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
254
|
+
<path fill-rule="evenodd" d="M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z" clip-rule="evenodd"></path>
|
255
|
+
</svg>
|
256
|
+
GitHub
|
257
|
+
</a>
|
258
|
+
</div>
|
259
|
+
|
260
|
+
</div>
|
261
|
+
|
262
|
+
<!-- Hero Section -->
|
263
|
+
<div class="hero min-h-screen bg-gradient-to-b from-base-100/50 to-transparent">
|
264
|
+
<div class="hero-content text-center">
|
265
|
+
<div class="max-w-4xl">
|
266
|
+
<div class="float mb-8">
|
267
|
+
<!-- Light mode logo -->
|
268
|
+
<img src="logo.svg" alt="Passive Queue Logo"
|
269
|
+
class="w-56 h-56 mx-auto mb-4 block logo-light" id="" style="width: 224px; height: 224px;">
|
270
|
+
<!-- Dark mode logo -->
|
271
|
+
<img src="logo-dark.svg" alt="Passive Queue Logo"
|
272
|
+
class="w-56 h-56 mx-auto mb-4 hidden logo-dark" id="" style="width: 224px; height: 224px;">
|
273
|
+
</div>
|
274
|
+
|
275
|
+
<script>
|
276
|
+
|
277
|
+
function updateLogos() {
|
278
|
+
// Check the actual applied theme instead of system preference
|
279
|
+
const currentTheme = document.documentElement.getAttribute('data-theme');
|
280
|
+
const lightLogos = document.querySelectorAll('.logo-light');
|
281
|
+
const darkLogos = document.querySelectorAll('.logo-dark');
|
282
|
+
|
283
|
+
if (currentTheme === 'dark') {
|
284
|
+
lightLogos.forEach(logo => logo.classList.add('hidden'));
|
285
|
+
darkLogos.forEach(logo => logo.classList.remove('hidden'));
|
286
|
+
} else {
|
287
|
+
lightLogos.forEach(logo => logo.classList.remove('hidden'));
|
288
|
+
darkLogos.forEach(logo => logo.classList.add('hidden'));
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
292
|
+
|
293
|
+
// Update on load and when system theme changes
|
294
|
+
updateLogos();
|
295
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateLogos);
|
296
|
+
</script>
|
297
|
+
<h1 class="text-6xl font-light text-base-content mb-6">
|
298
|
+
Passive Queue
|
299
|
+
</h1>
|
300
|
+
<p class="text-xl font-light text-base-content/70 mb-2">
|
301
|
+
The Rails Job Processing Backend That Finally Gets It
|
302
|
+
</p>
|
303
|
+
<p class="text-lg font-extralight text-base-content/60 mb-8 italic">
|
304
|
+
"Why do today what you can put off indefinitely?"
|
305
|
+
</p>
|
306
|
+
<div class="flex flex-col sm:flex-row gap-4 justify-center items-center">
|
307
|
+
<a href="#install" class="btn btn-primary btn-lg">
|
308
|
+
Get Started Right Now!
|
309
|
+
</a>
|
310
|
+
<button class="btn btn-outline btn-lg">
|
311
|
+
View Documentation
|
312
|
+
</button>
|
313
|
+
</div>
|
314
|
+
<div class="mt-8 text-sm text-base-content/80">
|
315
|
+
✨ 100% Free ✨ Zero Dependencies ✨ Infinite Scalability
|
316
|
+
</div>
|
317
|
+
</div>
|
318
|
+
</div>
|
319
|
+
</div>
|
320
|
+
|
321
|
+
<!-- Features Section -->
|
322
|
+
<section id="features" class="py-20 bg-base-100">
|
323
|
+
<div class="container mx-auto px-4">
|
324
|
+
<div class="text-center mb-16">
|
325
|
+
<h2 class="text-4xl font-light mb-4">Why Choose Passive Queue?</h2>
|
326
|
+
<p class="text-lg text-base-content/70 max-w-2xl mx-auto">
|
327
|
+
Embrace the zen of non-execution with features designed for the modern mindful developer
|
328
|
+
</p>
|
329
|
+
</div>
|
330
|
+
|
331
|
+
<div class="grid md:grid-cols-3 gap-8 max-w-6xl mx-auto">
|
332
|
+
<div class="card bg-base-300 peaceful-shadow">
|
333
|
+
<div class="card-body text-center">
|
334
|
+
<div class="text-4xl mb-4">🎯</div>
|
335
|
+
<h3 class="card-title justify-center mb-2 font-medium">100% Reliable Non-Execution</h3>
|
336
|
+
<p class="text-base-content/70">Every job you schedule is guaranteed to not run. Zero false positives - your tasks will never accidentally complete.</p>
|
337
|
+
</div>
|
338
|
+
</div>
|
339
|
+
|
340
|
+
<div class="card bg-base-300 peaceful-shadow">
|
341
|
+
<div class="card-body text-center">
|
342
|
+
<div class="text-4xl mb-4">⚡</div>
|
343
|
+
<h3 class="card-title justify-center mb-2 font-medium">Blazing Fast Non-Performance</h3>
|
344
|
+
<p class="text-base-content/70">Completes in 0ms every time. Infinite scalability since nothing scales faster than nothing.</p>
|
345
|
+
</div>
|
346
|
+
</div>
|
347
|
+
|
348
|
+
<div class="card bg-base-300 peaceful-shadow">
|
349
|
+
<div class="card-body text-center">
|
350
|
+
<div class="text-4xl mb-4">🔧</div>
|
351
|
+
<h3 class="card-title justify-center mb-2 font-medium">Drop-in Replacement</h3>
|
352
|
+
<p class="text-base-content/70">Simply set Passive Queue as your queue adapter. All your existing jobs will gracefully do nothing.</p>
|
353
|
+
</div>
|
354
|
+
</div>
|
355
|
+
|
356
|
+
<div class="card bg-base-300 peaceful-shadow">
|
357
|
+
<div class="card-body text-center">
|
358
|
+
<div class="text-4xl mb-4">📊</div>
|
359
|
+
<h3 class="card-title justify-center mb-2 font-medium">Advanced Non-Monitoring</h3>
|
360
|
+
<p class="text-base-content/70">Real-time dashboard showing exactly how much isn't happening with detailed logs of non-executed tasks.</p>
|
361
|
+
</div>
|
362
|
+
</div>
|
363
|
+
|
364
|
+
<div class="card bg-base-300 peaceful-shadow">
|
365
|
+
<div class="card-body text-center">
|
366
|
+
<div class="text-4xl mb-4">🧘</div>
|
367
|
+
<h3 class="card-title justify-center mb-2 font-medium">Zen Mode Integration</h3>
|
368
|
+
<p class="text-base-content/70">Built-in mindfulness features including <code>bundle exec be passive</code> for ultimate developer tranquility.</p>
|
369
|
+
</div>
|
370
|
+
</div>
|
371
|
+
|
372
|
+
<div class="card bg-base-300 peaceful-shadow">
|
373
|
+
<div class="card-body text-center">
|
374
|
+
<div class="text-4xl mb-4">💚</div>
|
375
|
+
<h3 class="card-title justify-center mb-2 font-medium">Zero Carbon Footprint</h3>
|
376
|
+
<p class="text-base-content/70">The most environmentally friendly job processor. When you do nothing, you consume nothing.</p>
|
377
|
+
</div>
|
378
|
+
</div>
|
379
|
+
</div>
|
380
|
+
</div>
|
381
|
+
</section>
|
382
|
+
|
383
|
+
<!-- Code Example -->
|
384
|
+
<section class="py-20 zen-gradient" id="install">
|
385
|
+
<div class="container mx-auto px-4">
|
386
|
+
<div class="text-center mb-12">
|
387
|
+
<h2 class="text-4xl font-light mb-4">Simple. Elegant. Nothing.</h2>
|
388
|
+
<p class="text-lg text-base-content/70">Getting started is as easy as doing nothing</p>
|
389
|
+
</div>
|
390
|
+
|
391
|
+
<div class="max-w-4xl mx-auto">
|
392
|
+
<div class="code-container peaceful-shadow">
|
393
|
+
<pre><code class="language-ruby"># 1. Add it to your Gemfile
|
394
|
+
gem "passive_queue"
|
395
|
+
|
396
|
+
# 2. Set it as your queue adapter
|
397
|
+
class Application < Rails::Application
|
398
|
+
# ...
|
399
|
+
config.active_job.queue_adapter = :passive_queue
|
400
|
+
end
|
401
|
+
|
402
|
+
# 3. Simply run it!
|
403
|
+
bundle exec be passive
|
404
|
+
|
405
|
+
# 4. Optionally you can also use the Web UI
|
406
|
+
Rails.application.routes.draw do
|
407
|
+
mount PassiveQueue::Engine => '/passive_queue'
|
408
|
+
end
|
409
|
+
</code></pre>
|
410
|
+
</div>
|
411
|
+
</div>
|
412
|
+
</div>
|
413
|
+
</section>
|
414
|
+
|
415
|
+
<!-- Live Demo Section -->
|
416
|
+
<section id="demo" class="py-20 bg-base-100">
|
417
|
+
<div class="container mx-auto px-4">
|
418
|
+
<div class="text-center mb-12">
|
419
|
+
<h2 class="text-4xl font-light mb-4">Live Demo</h2>
|
420
|
+
<p class="text-lg text-base-content/70">Experience Passive Queue in action</p>
|
421
|
+
</div>
|
422
|
+
|
423
|
+
<div class="max-w-4xl mx-auto">
|
424
|
+
<div class="card bg-base-300 peaceful-shadow">
|
425
|
+
<div class="card-body">
|
426
|
+
<h3 class="card-title justify-center mb-4">Passive Queue Dashboard</h3>
|
427
|
+
<div class="bg-base-200 stats stats-vertical lg:stats-horizontal shadow">
|
428
|
+
<div class="stat">
|
429
|
+
<div class="stat-title">Jobs Queued</div>
|
430
|
+
<div class="stat-value text-primary">∞</div>
|
431
|
+
<div class="stat-desc">All waiting peacefully</div>
|
432
|
+
</div>
|
433
|
+
<div class="stat">
|
434
|
+
<div class="stat-title">Jobs Processed</div>
|
435
|
+
<div class="stat-value text-secondary">0</div>
|
436
|
+
<div class="stat-desc">Perfect execution rate</div>
|
437
|
+
</div>
|
438
|
+
<div class="stat">
|
439
|
+
<div class="stat-title">Uptime</div>
|
440
|
+
<div class="stat-value text-accent">100%</div>
|
441
|
+
<div class="stat-desc">Of doing nothing</div>
|
442
|
+
</div>
|
443
|
+
</div>
|
444
|
+
|
445
|
+
<div class="mt-6">
|
446
|
+
<button class="btn btn-primary w-full" onclick="simulateJob()">
|
447
|
+
Schedule Demo Job
|
448
|
+
</button>
|
449
|
+
<div id="demo-output" class="mt-8 code-container peaceful-shadow">
|
450
|
+
<pre><code class="language-ruby"># Waiting for job to be scheduled...</code></pre>
|
451
|
+
</div>
|
452
|
+
</div>
|
453
|
+
</div>
|
454
|
+
</div>
|
455
|
+
</div>
|
456
|
+
</div>
|
457
|
+
</section>
|
458
|
+
<!-- Pricing Section -->
|
459
|
+
<section id="pricing" class="py-20 zen-gradient">
|
460
|
+
<div class="container mx-auto px-4">
|
461
|
+
<div class="text-center mb-16">
|
462
|
+
<h2 class="text-4xl font-light mb-4">Simple, Transparent Pricing</h2>
|
463
|
+
<p class="text-lg text-base-content/70">Pay nothing, get nothing. It's that simple.</p>
|
464
|
+
</div>
|
465
|
+
|
466
|
+
<div class="grid md:grid-cols-3 gap-8 max-w-6xl mx-auto">
|
467
|
+
<!-- Free Tier -->
|
468
|
+
<div class="card bg-base-100 peaceful-shadow">
|
469
|
+
<div class="card-body">
|
470
|
+
<h3 class="card-title justify-center text-2xl font-light">Free</h3>
|
471
|
+
<div class="text-center">
|
472
|
+
<div class="text-5xl font-light mb-2">$0</div>
|
473
|
+
<div class="text-base-content/60">forever</div>
|
474
|
+
</div>
|
475
|
+
<div class="divider"></div>
|
476
|
+
<ul class="space-y-2">
|
477
|
+
<li class="flex items-center">
|
478
|
+
<span class="text-success mr-2">✓</span>
|
479
|
+
Up to ∞ jobs that won't run
|
480
|
+
</li>
|
481
|
+
<li class="flex items-center">
|
482
|
+
<span class="text-success mr-2">✓</span>
|
483
|
+
Basic non-monitoring
|
484
|
+
</li>
|
485
|
+
<li class="flex items-center">
|
486
|
+
<span class="text-success mr-2">✓</span>
|
487
|
+
Community non-support
|
488
|
+
</li>
|
489
|
+
<li class="flex items-center">
|
490
|
+
<span class="text-success mr-2">✓</span>
|
491
|
+
Zero carbon footprint
|
492
|
+
</li>
|
493
|
+
</ul>
|
494
|
+
<div class="card-actions justify-center mt-6">
|
495
|
+
<a href="#install" class="btn btn-outline btn-wide">Get Started</a>
|
496
|
+
</div>
|
497
|
+
</div>
|
498
|
+
</div>
|
499
|
+
|
500
|
+
<!-- Pro Tier -->
|
501
|
+
<div class="card bg-base-100 peaceful-shadow border-2 border-primary">
|
502
|
+
<div class="badge badge-primary absolute top-4 right-4">Most Popular</div>
|
503
|
+
<div class="card-body">
|
504
|
+
<h3 class="card-title justify-center text-2xl font-light">Pro</h3>
|
505
|
+
<div class="text-center">
|
506
|
+
<div class="text-5xl font-light mb-2">$0</div>
|
507
|
+
<div class="text-base-content/60">per month</div>
|
508
|
+
</div>
|
509
|
+
<div class="divider"></div>
|
510
|
+
<ul class="space-y-2">
|
511
|
+
<li class="flex items-center">
|
512
|
+
<span class="text-success mr-2">✓</span>
|
513
|
+
Everything in Free
|
514
|
+
</li>
|
515
|
+
<li class="flex items-center">
|
516
|
+
<span class="text-success mr-2">✓</span>
|
517
|
+
Advanced non-analytics
|
518
|
+
</li>
|
519
|
+
<li class="flex items-center">
|
520
|
+
<span class="text-success mr-2">✓</span>
|
521
|
+
Priority non-execution
|
522
|
+
</li>
|
523
|
+
<li class="flex items-center">
|
524
|
+
<span class="text-success mr-2">✓</span>
|
525
|
+
Zen koans included
|
526
|
+
</li>
|
527
|
+
<li class="flex items-center">
|
528
|
+
<span class="text-success mr-2">✓</span>
|
529
|
+
24/7 non-support
|
530
|
+
</li>
|
531
|
+
</ul>
|
532
|
+
<div class="card-actions justify-center mt-6">
|
533
|
+
<a href="#install" class="btn btn-primary btn-wide">Choose Pro</a>
|
534
|
+
</div>
|
535
|
+
</div>
|
536
|
+
</div>
|
537
|
+
|
538
|
+
<!-- Enterprise Tier -->
|
539
|
+
<div class="card bg-base-100 peaceful-shadow">
|
540
|
+
<div class="card-body">
|
541
|
+
<h3 class="card-title justify-center text-2xl font-light">Enterprise</h3>
|
542
|
+
<div class="text-center">
|
543
|
+
<div class="text-5xl font-light mb-2">$0</div>
|
544
|
+
<div class="text-base-content/60">per month</div>
|
545
|
+
</div>
|
546
|
+
<div class="divider"></div>
|
547
|
+
<ul class="space-y-2">
|
548
|
+
<li class="flex items-center">
|
549
|
+
<span class="text-success mr-2">✓</span>
|
550
|
+
Everything in Pro
|
551
|
+
</li>
|
552
|
+
<li class="flex items-center">
|
553
|
+
<span class="text-success mr-2">✓</span>
|
554
|
+
Dedicated non-account manager
|
555
|
+
</li>
|
556
|
+
<li class="flex items-center">
|
557
|
+
<span class="text-success mr-2">✓</span>
|
558
|
+
Custom non-integrations
|
559
|
+
</li>
|
560
|
+
<li class="flex items-center">
|
561
|
+
<span class="text-success mr-2">✓</span>
|
562
|
+
SLA guaranteeing 99.99% non-uptime
|
563
|
+
</li>
|
564
|
+
<li class="flex items-center">
|
565
|
+
<span class="text-success mr-2">✓</span>
|
566
|
+
On-premise nothing deployment
|
567
|
+
</li>
|
568
|
+
</ul>
|
569
|
+
<div class="card-actions justify-center mt-6">
|
570
|
+
<a href="mailto:void@passivequeue.io" class="btn btn-outline btn-wide">Contact Sales</a>
|
571
|
+
</div>
|
572
|
+
</div>
|
573
|
+
</div>
|
574
|
+
</div>
|
575
|
+
</div>
|
576
|
+
</section>
|
577
|
+
|
578
|
+
<!-- Testimonials -->
|
579
|
+
<section class="py-20 bg-base-100">
|
580
|
+
<div class="container mx-auto px-4">
|
581
|
+
<div class="text-center mb-16">
|
582
|
+
<h2 class="text-4xl font-light mb-4">What Our Users Are Saying</h2>
|
583
|
+
<p class="text-lg text-base-content/80">Real feedback from developers who've achieved true non-productivity</p>
|
584
|
+
</div>
|
585
|
+
|
586
|
+
<div class="grid md:grid-cols-3 gap-8 max-w-6xl mx-auto">
|
587
|
+
<div class="card bg-base-300 peaceful-shadow">
|
588
|
+
<div class="card-body">
|
589
|
+
<p class="text-base-content/80 mb-4">"I scheduled 10,000 jobs last month and Passive Queue delivered on its promise - not a single one ran. Amazing!"</p>
|
590
|
+
<div class="flex items-center">
|
591
|
+
<div class="avatar placeholder mr-3">
|
592
|
+
<div class="bg-neutral text-center p-2 text-neutral-content rounded-full w-10">
|
593
|
+
<span class="text-sm">SK</span>
|
594
|
+
</div>
|
595
|
+
</div>
|
596
|
+
<div>
|
597
|
+
<div class="font-medium">Sarah K.</div>
|
598
|
+
<div class="text-sm text-base-content/60">Senior Procrastination Engineer</div>
|
599
|
+
</div>
|
600
|
+
</div>
|
601
|
+
</div>
|
602
|
+
</div>
|
603
|
+
|
604
|
+
<div class="card bg-base-300 peaceful-shadow">
|
605
|
+
<div class="card-body">
|
606
|
+
<p class="text-base-content/80 mb-4">"Finally, a job processor that matches my work ethic. Passive Queue has revolutionized how I don't approach background tasks."</p>
|
607
|
+
<div class="flex items-center">
|
608
|
+
<div class="avatar placeholder mr-3">
|
609
|
+
<div class="bg-primary text-center p-2 text-primary-content rounded-full w-10">
|
610
|
+
<span class="text-sm">MT</span>
|
611
|
+
</div>
|
612
|
+
</div>
|
613
|
+
<div>
|
614
|
+
<div class="font-medium">Mike T.</div>
|
615
|
+
<div class="text-sm text-base-content/60">Professional Postponer</div>
|
616
|
+
</div>
|
617
|
+
</div>
|
618
|
+
</div>
|
619
|
+
</div>
|
620
|
+
|
621
|
+
<div class="card bg-base-300 peaceful-shadow">
|
622
|
+
<div class="card-body">
|
623
|
+
<p class="text-base-content/80 mb-4">"Our productivity has never been lower. The peace of mind knowing nothing will ever execute accidentally is priceless."</p>
|
624
|
+
<div class="flex items-center">
|
625
|
+
<div class="avatar placeholder mr-3">
|
626
|
+
<div class="bg-secondary text-center p-2 text-secondary-content rounded-full w-10">
|
627
|
+
<span class="text-sm">DT</span>
|
628
|
+
</div>
|
629
|
+
</div>
|
630
|
+
<div>
|
631
|
+
<div class="font-medium">DevOps Team</div>
|
632
|
+
<div class="text-sm text-base-content/60">Startup McStartupface</div>
|
633
|
+
</div>
|
634
|
+
</div>
|
635
|
+
</div>
|
636
|
+
</div>
|
637
|
+
<div class="card bg-base-300 peaceful-shadow">
|
638
|
+
<div class="card-body">
|
639
|
+
<p class="text-base-content/80 mb-4">"Since switching to Passive Queue, our newsletter emails never end up in spam folders. Our customers love the mystery of our non-communication strategy!"</p>
|
640
|
+
<div class="flex items-center">
|
641
|
+
<div class="avatar placeholder mr-3">
|
642
|
+
<div class="bg-accent text-center p-2 text-accent-content rounded-full w-10">
|
643
|
+
<span class="text-sm">JR</span>
|
644
|
+
</div>
|
645
|
+
</div>
|
646
|
+
<div>
|
647
|
+
<div class="font-medium">Jessica R.</div>
|
648
|
+
<div class="text-sm text-base-content/60">Email Marketing Zen Master</div>
|
649
|
+
</div>
|
650
|
+
</div>
|
651
|
+
</div>
|
652
|
+
</div>
|
653
|
+
|
654
|
+
<div class="card bg-base-300 peaceful-shadow">
|
655
|
+
<div class="card-body">
|
656
|
+
<p class="text-base-content/80 mb-4">"Our data processing jobs can't corrupt the database if they never run. We've achieved 100% data integrity through the power of inaction!"</p>
|
657
|
+
<div class="flex items-center">
|
658
|
+
<div class="avatar placeholder mr-3">
|
659
|
+
<div class="bg-warning text-center p-2 text-warning-content rounded-full w-10">
|
660
|
+
<span class="text-sm">AL</span>
|
661
|
+
</div>
|
662
|
+
</div>
|
663
|
+
<div>
|
664
|
+
<div class="font-medium">Alex L.</div>
|
665
|
+
<div class="text-sm text-base-content/60">Data Integrity Philosopher</div>
|
666
|
+
</div>
|
667
|
+
</div>
|
668
|
+
</div>
|
669
|
+
</div>
|
670
|
+
|
671
|
+
<div class="card bg-base-300 peaceful-shadow">
|
672
|
+
<div class="card-body">
|
673
|
+
<p class="text-base-content/80 mb-4">"Image resizing tasks that don't execute can't fill up our disk space. We've solved our storage problems by embracing the void. Genius!"</p>
|
674
|
+
<div class="flex items-center">
|
675
|
+
<div class="avatar placeholder mr-3">
|
676
|
+
<div class="bg-info text-center p-2 text-info-content rounded-full w-10">
|
677
|
+
<span class="text-sm">CM</span>
|
678
|
+
</div>
|
679
|
+
</div>
|
680
|
+
<div>
|
681
|
+
<div class="font-medium">Carlos M.</div>
|
682
|
+
<div class="text-sm text-base-content/60">Storage Optimization Guru</div>
|
683
|
+
</div>
|
684
|
+
</div>
|
685
|
+
</div>
|
686
|
+
</div>
|
687
|
+
</div>
|
688
|
+
</div>
|
689
|
+
|
690
|
+
|
691
|
+
|
692
|
+
</section>
|
693
|
+
|
694
|
+
<!-- Benchmark Section -->
|
695
|
+
<section class="py-20 zen-gradient">
|
696
|
+
<div class="container mx-auto px-4">
|
697
|
+
<div class="text-center mb-16">
|
698
|
+
<h2 class="text-4xl font-light mb-4">Performance Benchmarks</h2>
|
699
|
+
<p class="text-lg text-base-content/70">See how Passive Queue outperforms the competition in key metrics</p>
|
700
|
+
</div>
|
701
|
+
|
702
|
+
<div class="max-w-6xl mx-auto">
|
703
|
+
<!-- Job Scheduling Speed -->
|
704
|
+
<div class="card bg-base-300 mb-8">
|
705
|
+
<div class="card-body">
|
706
|
+
<h3 class="card-title text-2xl font-light mb-6 justify-center">Job Scheduling Speed</h3>
|
707
|
+
<div class="overflow-x-auto">
|
708
|
+
<table class="table table-zebra w-full">
|
709
|
+
<thead>
|
710
|
+
<tr>
|
711
|
+
<th>Queue System</th>
|
712
|
+
<th>Jobs/Second</th>
|
713
|
+
<th>Latency (ms)</th>
|
714
|
+
<th>Memory Usage</th>
|
715
|
+
</tr>
|
716
|
+
</thead>
|
717
|
+
<tbody>
|
718
|
+
<tr class="hover">
|
719
|
+
<td>
|
720
|
+
<div class="flex items-center space-x-3">
|
721
|
+
<div class="avatar placeholder">
|
722
|
+
<div class="bg-success text-center p-1 text-success-content rounded w-8 h-8">
|
723
|
+
<span class="text-xs">PQ</span>
|
724
|
+
</div>
|
725
|
+
</div>
|
726
|
+
<div class="font-bold text-success">Passive Queue</div>
|
727
|
+
</div>
|
728
|
+
</td>
|
729
|
+
<td><span class="badge badge-success">10,000,000</span></td>
|
730
|
+
<td><span class="badge badge-success">0ms</span></td>
|
731
|
+
<td><span class="badge badge-success">0 MB</span></td>
|
732
|
+
</tr>
|
733
|
+
<tr>
|
734
|
+
<td>
|
735
|
+
<div class="flex items-center space-x-3">
|
736
|
+
<div class="avatar placeholder">
|
737
|
+
<div class="bg-warning text-center p-1 text-warning-content rounded w-8 h-8">
|
738
|
+
<span class="text-xs">SQ</span>
|
739
|
+
</div>
|
740
|
+
</div>
|
741
|
+
<div>Sidekiq</div>
|
742
|
+
</div>
|
743
|
+
</td>
|
744
|
+
<td>4,137</td>
|
745
|
+
<td>2.3ms</td>
|
746
|
+
<td>45 MB</td>
|
747
|
+
</tr>
|
748
|
+
<tr>
|
749
|
+
<td>
|
750
|
+
<div class="flex items-center space-x-3">
|
751
|
+
<div class="avatar placeholder">
|
752
|
+
<div class="bg-info text-center p-1 text-info-content rounded w-8 h-8">
|
753
|
+
<span class="text-xs">SQ</span>
|
754
|
+
</div>
|
755
|
+
</div>
|
756
|
+
<div>Solid Queue</div>
|
757
|
+
</div>
|
758
|
+
</td>
|
759
|
+
<td>1,932</td>
|
760
|
+
<td>3.1ms</td>
|
761
|
+
<td>32 MB</td>
|
762
|
+
</tr>
|
763
|
+
<tr>
|
764
|
+
<td>
|
765
|
+
<div class="flex items-center space-x-3">
|
766
|
+
<div class="avatar placeholder">
|
767
|
+
<div class="bg-secondary text-center p-1 text-secondary-content rounded w-8 h-8">
|
768
|
+
<span class="text-xs">KF</span>
|
769
|
+
</div>
|
770
|
+
</div>
|
771
|
+
<div>Karafka</div>
|
772
|
+
</div>
|
773
|
+
</td>
|
774
|
+
<td>22,850</td>
|
775
|
+
<td>1.8ms</td>
|
776
|
+
<td>78 MB</td>
|
777
|
+
</tr>
|
778
|
+
</tbody>
|
779
|
+
</table>
|
780
|
+
</div>
|
781
|
+
</div>
|
782
|
+
</div>
|
783
|
+
|
784
|
+
<!-- Job Execution Speed -->
|
785
|
+
<div class="card bg-base-300 mb-8">
|
786
|
+
<div class="card-body">
|
787
|
+
<h3 class="card-title text-2xl font-light mb-6 justify-center">Job Execution Performance</h3>
|
788
|
+
<div class="overflow-x-auto">
|
789
|
+
<table class="table table-zebra w-full">
|
790
|
+
<thead>
|
791
|
+
<tr>
|
792
|
+
<th>Queue System</th>
|
793
|
+
<th>Avg Execution Time</th>
|
794
|
+
<th>Success Rate</th>
|
795
|
+
<th>Failed Jobs</th>
|
796
|
+
<th>Retry Overhead</th>
|
797
|
+
</tr>
|
798
|
+
</thead>
|
799
|
+
<tbody>
|
800
|
+
<tr class="hover">
|
801
|
+
<td>
|
802
|
+
<div class="flex items-center space-x-3">
|
803
|
+
<div class="avatar placeholder">
|
804
|
+
<div class="bg-success text-center p-1 text-success-content rounded w-8 h-8">
|
805
|
+
<span class="text-xs">PQ</span>
|
806
|
+
</div>
|
807
|
+
</div>
|
808
|
+
<div class="font-bold text-success">Passive Queue</div>
|
809
|
+
</div>
|
810
|
+
</td>
|
811
|
+
<td><span class="badge badge-success">0ms</span></td>
|
812
|
+
<td><span class="badge badge-success">100%</span></td>
|
813
|
+
<td><span class="badge badge-success">0</span></td>
|
814
|
+
<td><span class="badge badge-success">None</span></td>
|
815
|
+
</tr>
|
816
|
+
<tr>
|
817
|
+
<td>
|
818
|
+
<div class="flex items-center space-x-3">
|
819
|
+
<div class="avatar placeholder">
|
820
|
+
<div class="bg-warning text-center p-1 text-warning-content rounded w-8 h-8">
|
821
|
+
<span class="text-xs">SQ</span>
|
822
|
+
</div>
|
823
|
+
</div>
|
824
|
+
<div>Sidekiq</div>
|
825
|
+
</div>
|
826
|
+
</td>
|
827
|
+
<td>127ms</td>
|
828
|
+
<td>97.3%</td>
|
829
|
+
<td>2.7%</td>
|
830
|
+
<td>High</td>
|
831
|
+
</tr>
|
832
|
+
<tr>
|
833
|
+
<td>
|
834
|
+
<div class="flex items-center space-x-3">
|
835
|
+
<div class="avatar placeholder">
|
836
|
+
<div class="bg-info text-center p-1 text-info-content rounded w-8 h-8">
|
837
|
+
<span class="text-xs">SQ</span>
|
838
|
+
</div>
|
839
|
+
</div>
|
840
|
+
<div>Solid Queue</div>
|
841
|
+
</div>
|
842
|
+
</td>
|
843
|
+
<td>156ms</td>
|
844
|
+
<td>96.8%</td>
|
845
|
+
<td>3.2%</td>
|
846
|
+
<td>Medium</td>
|
847
|
+
</tr>
|
848
|
+
<tr>
|
849
|
+
<td>
|
850
|
+
<div class="flex items-center space-x-3">
|
851
|
+
<div class="avatar placeholder">
|
852
|
+
<div class="bg-secondary text-center p-1 text-secondary-content rounded w-8 h-8">
|
853
|
+
<span class="text-xs">KF</span>
|
854
|
+
</div>
|
855
|
+
</div>
|
856
|
+
<div>Karafka</div>
|
857
|
+
</div>
|
858
|
+
</td>
|
859
|
+
<td>89ms</td>
|
860
|
+
<td>98.1%</td>
|
861
|
+
<td>1.9%</td>
|
862
|
+
<td>Low</td>
|
863
|
+
</tr>
|
864
|
+
</tbody>
|
865
|
+
</table>
|
866
|
+
</div>
|
867
|
+
</div>
|
868
|
+
</div>
|
869
|
+
|
870
|
+
<!-- Scalability Chart -->
|
871
|
+
<div class="card bg-base-300 mb-8">
|
872
|
+
<div class="card-body">
|
873
|
+
<h3 class="card-title text-2xl font-light mb-6 justify-center">Scalability Under Load</h3>
|
874
|
+
<div class="grid md:grid-cols-2 gap-8">
|
875
|
+
<div>
|
876
|
+
<h4 class="font-medium mb-4">CPU Usage at 100k Jobs/hour</h4>
|
877
|
+
<div class="space-y-3">
|
878
|
+
<div class="flex justify-between items-center">
|
879
|
+
<span>Passive Queue</span>
|
880
|
+
<div class="flex items-center space-x-2">
|
881
|
+
<progress class="progress progress-success w-32" value="0" max="100"></progress>
|
882
|
+
<span class="text-sm font-mono">0%</span>
|
883
|
+
</div>
|
884
|
+
</div>
|
885
|
+
<div class="flex justify-between items-center">
|
886
|
+
<span>Sidekiq</span>
|
887
|
+
<div class="flex items-center space-x-2">
|
888
|
+
<progress class="progress progress-warning w-32" value="85" max="100"></progress>
|
889
|
+
<span class="text-sm font-mono">85%</span>
|
890
|
+
</div>
|
891
|
+
</div>
|
892
|
+
<div class="flex justify-between items-center">
|
893
|
+
<span>Solid Queue</span>
|
894
|
+
<div class="flex items-center space-x-2">
|
895
|
+
<progress class="progress progress-info w-32" value="78" max="100"></progress>
|
896
|
+
<span class="text-sm font-mono">78%</span>
|
897
|
+
</div>
|
898
|
+
</div>
|
899
|
+
<div class="flex justify-between items-center">
|
900
|
+
<span>Karafka</span>
|
901
|
+
<div class="flex items-center space-x-2">
|
902
|
+
<progress class="progress progress-secondary w-32" value="92" max="100"></progress>
|
903
|
+
<span class="text-sm font-mono">92%</span>
|
904
|
+
</div>
|
905
|
+
</div>
|
906
|
+
</div>
|
907
|
+
</div>
|
908
|
+
|
909
|
+
<div>
|
910
|
+
<h4 class="font-medium mb-4">Memory Usage Growth</h4>
|
911
|
+
<div class="space-y-3">
|
912
|
+
<div class="flex justify-between items-center">
|
913
|
+
<span>Passive Queue</span>
|
914
|
+
<div class="flex items-center space-x-2">
|
915
|
+
<progress class="progress progress-success w-32" value="0" max="100"></progress>
|
916
|
+
<span class="text-sm font-mono">0 MB</span>
|
917
|
+
</div>
|
918
|
+
</div>
|
919
|
+
<div class="flex justify-between items-center">
|
920
|
+
<span>Sidekiq</span>
|
921
|
+
<div class="flex items-center space-x-2">
|
922
|
+
<progress class="progress progress-warning w-32" value="70" max="100"></progress>
|
923
|
+
<span class="text-sm font-mono">1.2 GB</span>
|
924
|
+
</div>
|
925
|
+
</div>
|
926
|
+
<div class="flex justify-between items-center">
|
927
|
+
<span>Solid Queue</span>
|
928
|
+
<div class="flex items-center space-x-2">
|
929
|
+
<progress class="progress progress-info w-32" value="45" max="100"></progress>
|
930
|
+
<span class="text-sm font-mono">780 MB</span>
|
931
|
+
</div>
|
932
|
+
</div>
|
933
|
+
<div class="flex justify-between items-center">
|
934
|
+
<span>Karafka</span>
|
935
|
+
<div class="flex items-center space-x-2">
|
936
|
+
<progress class="progress progress-secondary w-32" value="95" max="100"></progress>
|
937
|
+
<span class="text-sm font-mono">1.8 GB</span>
|
938
|
+
</div>
|
939
|
+
</div>
|
940
|
+
</div>
|
941
|
+
</div>
|
942
|
+
</div>
|
943
|
+
</div>
|
944
|
+
</div>
|
945
|
+
|
946
|
+
<!-- Key Insights -->
|
947
|
+
<div class="stats stats-vertical lg:stats-horizontal w-full mb-8 bg-base-300">
|
948
|
+
<div class="stat">
|
949
|
+
<div class="stat-title text-center">Speed Advantage</div>
|
950
|
+
<div class="stat-value text-primary text-center">∞x</div>
|
951
|
+
<div class="stat-desc text-center">Faster than any competitor</div>
|
952
|
+
</div>
|
953
|
+
|
954
|
+
<div class="stat">
|
955
|
+
<div class="stat-title text-center">Cost Savings</div>
|
956
|
+
<div class="stat-value text-secondary text-center">100%</div>
|
957
|
+
<div class="stat-desc text-center">Zero infrastructure costs</div>
|
958
|
+
</div>
|
959
|
+
|
960
|
+
<div class="stat">
|
961
|
+
<div class="stat-title text-center">Energy Efficiency</div>
|
962
|
+
<div class="stat-value text-accent text-center">Perfect</div>
|
963
|
+
<div class="stat-desc text-center">Zero carbon footprint</div>
|
964
|
+
</div>
|
965
|
+
</div>
|
966
|
+
|
967
|
+
<!-- Disclaimer -->
|
968
|
+
<div class="alert alert-warning">
|
969
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
|
970
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16c-.77.833.192 2.5 1.732 2.5z" />
|
971
|
+
</svg>
|
972
|
+
<div>
|
973
|
+
<div class="font-medium">Benchmark Disclaimer</div>
|
974
|
+
<div class="text-sm">* All benchmark data has been carefully fabricated for entertainment purposes. Passive Queue's performance is theoretically perfect because it literally does nothing. Results may vary in production environments.</div>
|
975
|
+
</div>
|
976
|
+
</div>
|
977
|
+
</div>
|
978
|
+
</div>
|
979
|
+
</section>
|
980
|
+
|
981
|
+
<!-- Documentation Teaser -->
|
982
|
+
<!-- Documentation Teaser -->
|
983
|
+
<section id="docs" class="py-20 bg-base-100">
|
984
|
+
<div class="container mx-auto px-4">
|
985
|
+
<div class="text-center mb-12">
|
986
|
+
<h2 class="text-4xl font-light mb-4">Documentation</h2>
|
987
|
+
<p class="text-lg text-base-content/70">Everything you need to know about doing nothing</p>
|
988
|
+
</div>
|
989
|
+
|
990
|
+
<div class="max-w-4xl mx-auto">
|
991
|
+
<div class="card bg-base-300 peaceful-shadow">
|
992
|
+
<div class="card-body">
|
993
|
+
<div class="prose max-w-none">
|
994
|
+
<p>Getting started with Passive Queue is refreshingly simple:</p>
|
995
|
+
|
996
|
+
<h4 class="text-2xl font-light mb-4 mt-4">Installation</h4>
|
997
|
+
<div class="code-container peaceful-shadow">
|
998
|
+
<pre><code class="language-ruby"># Gemfile:
|
999
|
+
gem "passive_queue"
|
1000
|
+
|
1001
|
+
# CLI command:
|
1002
|
+
bundle install</code></pre>
|
1003
|
+
</div>
|
1004
|
+
|
1005
|
+
<h4 class="text-2xl font-light mb-4 mt-4">Configuration</h4>
|
1006
|
+
<div class="code-container peaceful-shadow">
|
1007
|
+
<pre><code class="language-ruby"># config/application.rb
|
1008
|
+
config.active_job.queue_adapter = :passive_queue</code></pre>
|
1009
|
+
</div>
|
1010
|
+
|
1011
|
+
<h4 class="text-2xl font-light mb-4 mt-4">The Art of Being Passive</h4>
|
1012
|
+
<div class="code-container peaceful-shadow">
|
1013
|
+
<pre><code class="language-bash"># Embrace the void
|
1014
|
+
bundle exec be passive
|
1015
|
+
# Meditate on your non-productivity
|
1016
|
+
bundle exec be passive --zen
|
1017
|
+
# Question the nature of execution
|
1018
|
+
bundle exec be passive --philosophical</code></pre>
|
1019
|
+
</div>
|
1020
|
+
|
1021
|
+
<div class="alert alert-info mt-6">
|
1022
|
+
<span class="text-info-content">
|
1023
|
+
💡 Pro tip: The most productive thing you can do is nothing. Passive Queue helps you achieve this zen state effortlessly.
|
1024
|
+
</span>
|
1025
|
+
</div>
|
1026
|
+
</div>
|
1027
|
+
|
1028
|
+
<div class="card-actions justify-center mt-8">
|
1029
|
+
<button class="btn btn-primary">View Full Documentation</button>
|
1030
|
+
<button class="btn btn-outline">API Reference</button>
|
1031
|
+
</div>
|
1032
|
+
</div>
|
1033
|
+
</div>
|
1034
|
+
</div>
|
1035
|
+
</div>
|
1036
|
+
</section>
|
1037
|
+
<!-- Footer -->
|
1038
|
+
<footer class="footer footer-center p-10 bg-base-200 text-base-content">
|
1039
|
+
<aside>
|
1040
|
+
<div class="text-4xl mb-4">
|
1041
|
+
<img src="logo.svg" alt="Passive Queue Logo"
|
1042
|
+
class="w-16 h-16 mx-auto mb-0 block mr-2 logo-light" id="" style="width: 34px; height: 34px;">
|
1043
|
+
<!-- Dark mode logo -->
|
1044
|
+
<img src="logo-dark.svg" alt="Passive Queue Logo"
|
1045
|
+
class="w-16 h-16 mx-auto mb-0 mr-2 hidden logo-dark" id="" style="width: 34px; height: 34px;">
|
1046
|
+
|
1047
|
+
</div>
|
1048
|
+
<p class="font-bold text-lg">Passive Queue</p>
|
1049
|
+
<p class="font-light">The Art of Non-Execution</p>
|
1050
|
+
<p class="text-sm text-base-content/60">© 2025 Maciej Mensfeld. All rights reserved. No jobs were harmed in the making of this product.</p>
|
1051
|
+
</aside>
|
1052
|
+
<nav>
|
1053
|
+
<div class="grid grid-flow-col gap-4">
|
1054
|
+
<a href="https://github.com/mensfeld/passive_queue" class="link link-hover">GitHub</a>
|
1055
|
+
<a href="#docs" class="link link-hover">Documentation</a>
|
1056
|
+
<a href="https://github.com/mensfeld/passive_queue/issues" class="link link-hover">Support</a>
|
1057
|
+
<a href="https://mensfeld.pl/tag/passive_queue/" class="link link-hover">Blog</a>
|
1058
|
+
</div>
|
1059
|
+
</nav>
|
1060
|
+
<nav>
|
1061
|
+
<div class="grid grid-flow-col gap-4">
|
1062
|
+
<a href="https://twitter.com/maciejmensfeld" class="btn btn-ghost btn-sm">
|
1063
|
+
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
1064
|
+
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
|
1065
|
+
</svg>
|
1066
|
+
</a>
|
1067
|
+
<a href="https://github.com/mensfeld/passive_queue" class="btn btn-ghost btn-sm">
|
1068
|
+
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
1069
|
+
<path fill-rule="evenodd" d="M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z" clip-rule="evenodd"></path>
|
1070
|
+
</svg>
|
1071
|
+
</a>
|
1072
|
+
</div>
|
1073
|
+
</nav>
|
1074
|
+
</footer>
|
1075
|
+
|
1076
|
+
<!-- JavaScript for Demo -->
|
1077
|
+
<script>
|
1078
|
+
function simulateJob() {
|
1079
|
+
const output = document.getElementById('demo-output');
|
1080
|
+
output.innerHTML = '<div class="loading loading-dots hljs-comment loading-lg"></div><div class="mt-2 hljs-comment">Scheduling job...</div>';
|
1081
|
+
|
1082
|
+
setTimeout(() => {
|
1083
|
+
output.innerHTML = `
|
1084
|
+
<div class="text-success">✓ Job scheduled successfully!</div>
|
1085
|
+
<div class="mt-2 text-white">Job ID: passive-job-${Date.now()}</div>
|
1086
|
+
<div class="mt-2 text-white">Status: Queued and being ignored</div>
|
1087
|
+
<div class="mt-2 text-white">Expected completion: Never</div>
|
1088
|
+
<div class="mt-4 text-info">🧘 Your job is now in a state of perfect non-execution</div>
|
1089
|
+
`;
|
1090
|
+
}, 2000);
|
1091
|
+
|
1092
|
+
setTimeout(() => {
|
1093
|
+
output.innerHTML += '<div class="mt-4 text-warning">💡 Fun fact: This job will consume 0 CPU cycles and 0 memory!</div>';
|
1094
|
+
}, 4000);
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
function updateLogos() {
|
1098
|
+
// Check the actual applied theme instead of system preference
|
1099
|
+
const currentTheme = document.documentElement.getAttribute('data-theme');
|
1100
|
+
const lightLogos = document.querySelectorAll('.logo-light');
|
1101
|
+
const darkLogos = document.querySelectorAll('.logo-dark');
|
1102
|
+
|
1103
|
+
if (currentTheme === 'dark') {
|
1104
|
+
lightLogos.forEach(logo => logo.classList.add('hidden'));
|
1105
|
+
darkLogos.forEach(logo => logo.classList.remove('hidden'));
|
1106
|
+
} else {
|
1107
|
+
lightLogos.forEach(logo => logo.classList.remove('hidden'));
|
1108
|
+
darkLogos.forEach(logo => logo.classList.add('hidden'));
|
1109
|
+
}
|
1110
|
+
}
|
1111
|
+
|
1112
|
+
// Theme toggle functionality
|
1113
|
+
function toggleTheme() {
|
1114
|
+
const html = document.querySelector('html');
|
1115
|
+
const currentTheme = html.getAttribute('data-theme');
|
1116
|
+
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
|
1117
|
+
html.setAttribute('data-theme', newTheme);
|
1118
|
+
localStorage.setItem('theme', newTheme);
|
1119
|
+
// Update logos
|
1120
|
+
updateLogos();
|
1121
|
+
}
|
1122
|
+
|
1123
|
+
// Load saved theme
|
1124
|
+
document.addEventListener('DOMContentLoaded', function() {
|
1125
|
+
const savedTheme = localStorage.getItem('theme') || 'light';
|
1126
|
+
document.querySelector('html').setAttribute('data-theme', savedTheme);
|
1127
|
+
});
|
1128
|
+
|
1129
|
+
// Smooth scrolling for anchor links
|
1130
|
+
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
1131
|
+
anchor.addEventListener('click', function (e) {
|
1132
|
+
e.preventDefault();
|
1133
|
+
const target = document.querySelector(this.getAttribute('href'));
|
1134
|
+
if (target) {
|
1135
|
+
target.scrollIntoView({
|
1136
|
+
behavior: 'smooth',
|
1137
|
+
block: 'start'
|
1138
|
+
});
|
1139
|
+
}
|
1140
|
+
});
|
1141
|
+
});
|
1142
|
+
|
1143
|
+
// Easter egg: Konami code for ultimate zen mode
|
1144
|
+
let konamiCode = [];
|
1145
|
+
const konamiSequence = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]; // ↑↑↓↓←→←→BA
|
1146
|
+
|
1147
|
+
document.addEventListener('keydown', function(e) {
|
1148
|
+
konamiCode.push(e.keyCode);
|
1149
|
+
if (konamiCode.length > konamiSequence.length) {
|
1150
|
+
konamiCode.shift();
|
1151
|
+
}
|
1152
|
+
|
1153
|
+
if (konamiCode.join(',') === konamiSequence.join(',')) {
|
1154
|
+
document.body.innerHTML = `
|
1155
|
+
<div class="hero min-h-screen bg-base-100 flex items-center justify-center">
|
1156
|
+
<div class="text-center">
|
1157
|
+
<div class="text-9xl mb-8 animate-spin">🧘♂️</div>
|
1158
|
+
<h1 class="text-6xl font-light mb-4">Ultimate Zen Mode Activated</h1>
|
1159
|
+
<p class="text-xl mb-8">You have achieved the highest level of non-productivity</p>
|
1160
|
+
<button class="btn btn-primary" onclick="location.reload()">Return to Reality</button>
|
1161
|
+
</div>
|
1162
|
+
</div>
|
1163
|
+
`;
|
1164
|
+
}
|
1165
|
+
});
|
1166
|
+
</script>
|
1167
|
+
<script>
|
1168
|
+
// Initialize highlight.js
|
1169
|
+
hljs.highlightAll();
|
1170
|
+
</script>
|
1171
|
+
|
1172
|
+
|
1173
|
+
|
1174
|
+
<script>
|
1175
|
+
// Theme management system
|
1176
|
+
let currentThemePreference = 'auto'; // Track current preference
|
1177
|
+
|
1178
|
+
function getSystemTheme() {
|
1179
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
1180
|
+
}
|
1181
|
+
|
1182
|
+
function applyTheme(theme) {
|
1183
|
+
currentThemePreference = theme;
|
1184
|
+
|
1185
|
+
if (theme === 'auto') {
|
1186
|
+
const systemTheme = getSystemTheme();
|
1187
|
+
document.documentElement.setAttribute('data-theme', systemTheme);
|
1188
|
+
return systemTheme;
|
1189
|
+
} else {
|
1190
|
+
document.documentElement.setAttribute('data-theme', theme);
|
1191
|
+
return theme;
|
1192
|
+
}
|
1193
|
+
}
|
1194
|
+
|
1195
|
+
function setTheme(theme) {
|
1196
|
+
localStorage.setItem('theme', theme);
|
1197
|
+
applyTheme(theme);
|
1198
|
+
updateLogos()
|
1199
|
+
}
|
1200
|
+
|
1201
|
+
function toggleTheme() {
|
1202
|
+
const themes = ['light', 'dark', 'auto'];
|
1203
|
+
const currentIndex = themes.indexOf(currentThemePreference);
|
1204
|
+
const nextTheme = themes[(currentIndex + 1) % themes.length];
|
1205
|
+
setTheme(nextTheme);
|
1206
|
+
updateLogos()
|
1207
|
+
}
|
1208
|
+
|
1209
|
+
function initTheme() {
|
1210
|
+
// Get saved theme or default to auto
|
1211
|
+
const savedTheme = localStorage.getItem('theme');
|
1212
|
+
const themeToApply = savedTheme !== null ? savedTheme : 'auto';
|
1213
|
+
|
1214
|
+
applyTheme(themeToApply);
|
1215
|
+
|
1216
|
+
// Listen for system theme changes
|
1217
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
|
1218
|
+
if (currentThemePreference === 'auto') {
|
1219
|
+
applyTheme('auto');
|
1220
|
+
}
|
1221
|
+
});
|
1222
|
+
|
1223
|
+
updateLogos()
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
// Run when DOM is ready
|
1227
|
+
if (document.readyState === 'loading') {
|
1228
|
+
document.addEventListener('DOMContentLoaded', initTheme);
|
1229
|
+
} else {
|
1230
|
+
initTheme();
|
1231
|
+
}
|
1232
|
+
|
1233
|
+
// Also run immediately to prevent flash
|
1234
|
+
initTheme();
|
1235
|
+
</script>
|
1236
|
+
</body>
|
1237
|
+
</html>
|