@exulu/backend 1.48.2 → 1.49.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.
- package/dist/index.cjs +351 -42
- package/dist/index.d.cts +96 -1
- package/dist/index.d.ts +96 -1
- package/dist/index.js +340 -38
- package/ee/{markdown.ts → chunking/markdown.ts} +2 -2
- package/ee/python/README.md +295 -0
- package/ee/python/documents/processing/README.md +155 -0
- package/ee/{documents → python/documents}/processing/doc_processor.ts +25 -17
- package/ee/{documents/processing/pdf_to_markdown.py → python/documents/processing/document_to_markdown.py} +3 -10
- package/ee/python/setup.sh +180 -0
- package/package.json +14 -3
- package/scripts/postinstall.cjs +149 -0
- package/.agents/skills/mintlify/SKILL.md +0 -347
- package/.editorconfig +0 -15
- package/.eslintrc.json +0 -52
- package/.github/workflows/release-backend.yml +0 -38
- package/.husky/commit-msg +0 -1
- package/.jscpd.json +0 -18
- package/.mcp.json +0 -25
- package/.nvmrc +0 -1
- package/.prettierignore +0 -5
- package/.prettierrc.json +0 -12
- package/CHANGELOG.md +0 -8
- package/SECURITY.md +0 -5
- package/commitlint.config.js +0 -4
- package/devops/documentation/patch-older-releases.md +0 -42
- package/ee/documents/processing/build_pdf_processor.sh +0 -35
- package/ee/documents/processing/chunk_markdown.py +0 -263
- package/ee/documents/processing/pdf_processor.spec +0 -115
- package/eslint.config.js +0 -88
- package/jest.config.ts +0 -25
- package/mintlify-docs/.mintignore +0 -7
- package/mintlify-docs/AGENTS.md +0 -33
- package/mintlify-docs/CLAUDE.MD +0 -50
- package/mintlify-docs/CONTRIBUTING.md +0 -32
- package/mintlify-docs/LICENSE +0 -21
- package/mintlify-docs/README.md +0 -55
- package/mintlify-docs/ai-tools/claude-code.mdx +0 -43
- package/mintlify-docs/ai-tools/cursor.mdx +0 -39
- package/mintlify-docs/ai-tools/windsurf.mdx +0 -39
- package/mintlify-docs/api-reference/core-types/agent-types.mdx +0 -110
- package/mintlify-docs/api-reference/core-types/analytics-types.mdx +0 -95
- package/mintlify-docs/api-reference/core-types/configuration-types.mdx +0 -83
- package/mintlify-docs/api-reference/core-types/evaluation-types.mdx +0 -106
- package/mintlify-docs/api-reference/core-types/job-types.mdx +0 -135
- package/mintlify-docs/api-reference/core-types/overview.mdx +0 -73
- package/mintlify-docs/api-reference/core-types/prompt-types.mdx +0 -102
- package/mintlify-docs/api-reference/core-types/rbac-types.mdx +0 -163
- package/mintlify-docs/api-reference/core-types/session-types.mdx +0 -77
- package/mintlify-docs/api-reference/core-types/user-management.mdx +0 -112
- package/mintlify-docs/api-reference/core-types/workflow-types.mdx +0 -88
- package/mintlify-docs/api-reference/core-types.mdx +0 -585
- package/mintlify-docs/api-reference/dynamic-types.mdx +0 -851
- package/mintlify-docs/api-reference/endpoint/create.mdx +0 -4
- package/mintlify-docs/api-reference/endpoint/delete.mdx +0 -4
- package/mintlify-docs/api-reference/endpoint/get.mdx +0 -4
- package/mintlify-docs/api-reference/endpoint/webhook.mdx +0 -4
- package/mintlify-docs/api-reference/introduction.mdx +0 -661
- package/mintlify-docs/api-reference/mutations.mdx +0 -1012
- package/mintlify-docs/api-reference/openapi.json +0 -217
- package/mintlify-docs/api-reference/queries.mdx +0 -1154
- package/mintlify-docs/backend/introduction.mdx +0 -218
- package/mintlify-docs/changelog.mdx +0 -387
- package/mintlify-docs/community-edition.mdx +0 -304
- package/mintlify-docs/core/exulu-agent/api-reference.mdx +0 -894
- package/mintlify-docs/core/exulu-agent/configuration.mdx +0 -690
- package/mintlify-docs/core/exulu-agent/introduction.mdx +0 -552
- package/mintlify-docs/core/exulu-app/api-reference.mdx +0 -481
- package/mintlify-docs/core/exulu-app/configuration.mdx +0 -319
- package/mintlify-docs/core/exulu-app/introduction.mdx +0 -117
- package/mintlify-docs/core/exulu-authentication.mdx +0 -810
- package/mintlify-docs/core/exulu-chunkers/api-reference.mdx +0 -1011
- package/mintlify-docs/core/exulu-chunkers/configuration.mdx +0 -596
- package/mintlify-docs/core/exulu-chunkers/introduction.mdx +0 -403
- package/mintlify-docs/core/exulu-context/api-reference.mdx +0 -911
- package/mintlify-docs/core/exulu-context/configuration.mdx +0 -648
- package/mintlify-docs/core/exulu-context/introduction.mdx +0 -394
- package/mintlify-docs/core/exulu-database.mdx +0 -811
- package/mintlify-docs/core/exulu-default-agents.mdx +0 -545
- package/mintlify-docs/core/exulu-eval/api-reference.mdx +0 -772
- package/mintlify-docs/core/exulu-eval/configuration.mdx +0 -680
- package/mintlify-docs/core/exulu-eval/introduction.mdx +0 -459
- package/mintlify-docs/core/exulu-logging.mdx +0 -464
- package/mintlify-docs/core/exulu-otel.mdx +0 -670
- package/mintlify-docs/core/exulu-queues/api-reference.mdx +0 -648
- package/mintlify-docs/core/exulu-queues/configuration.mdx +0 -650
- package/mintlify-docs/core/exulu-queues/introduction.mdx +0 -474
- package/mintlify-docs/core/exulu-reranker/api-reference.mdx +0 -630
- package/mintlify-docs/core/exulu-reranker/configuration.mdx +0 -663
- package/mintlify-docs/core/exulu-reranker/introduction.mdx +0 -516
- package/mintlify-docs/core/exulu-tool/api-reference.mdx +0 -723
- package/mintlify-docs/core/exulu-tool/configuration.mdx +0 -805
- package/mintlify-docs/core/exulu-tool/introduction.mdx +0 -539
- package/mintlify-docs/core/exulu-variables/api-reference.mdx +0 -699
- package/mintlify-docs/core/exulu-variables/configuration.mdx +0 -736
- package/mintlify-docs/core/exulu-variables/introduction.mdx +0 -511
- package/mintlify-docs/development.mdx +0 -94
- package/mintlify-docs/docs.json +0 -248
- package/mintlify-docs/enterprise-edition.mdx +0 -538
- package/mintlify-docs/essentials/code.mdx +0 -35
- package/mintlify-docs/essentials/images.mdx +0 -59
- package/mintlify-docs/essentials/markdown.mdx +0 -88
- package/mintlify-docs/essentials/navigation.mdx +0 -87
- package/mintlify-docs/essentials/reusable-snippets.mdx +0 -110
- package/mintlify-docs/essentials/settings.mdx +0 -318
- package/mintlify-docs/favicon.svg +0 -3
- package/mintlify-docs/frontend/introduction.mdx +0 -39
- package/mintlify-docs/getting-started.mdx +0 -267
- package/mintlify-docs/guides/custom-agent.mdx +0 -608
- package/mintlify-docs/guides/first-agent.mdx +0 -315
- package/mintlify-docs/images/admin_ui.png +0 -0
- package/mintlify-docs/images/contexts.png +0 -0
- package/mintlify-docs/images/create_agents.png +0 -0
- package/mintlify-docs/images/evals.png +0 -0
- package/mintlify-docs/images/graphql.png +0 -0
- package/mintlify-docs/images/graphql_api.png +0 -0
- package/mintlify-docs/images/hero-dark.png +0 -0
- package/mintlify-docs/images/hero-light.png +0 -0
- package/mintlify-docs/images/hero.png +0 -0
- package/mintlify-docs/images/knowledge_sources.png +0 -0
- package/mintlify-docs/images/mcp.png +0 -0
- package/mintlify-docs/images/scaling.png +0 -0
- package/mintlify-docs/index.mdx +0 -411
- package/mintlify-docs/logo/dark.svg +0 -9
- package/mintlify-docs/logo/light.svg +0 -9
- package/mintlify-docs/partners.mdx +0 -558
- package/mintlify-docs/products.mdx +0 -77
- package/mintlify-docs/snippets/snippet-intro.mdx +0 -4
- package/mintlify-docs/styles.css +0 -207
- package/ngrok.bash +0 -1
- package/ngrok.md +0 -6
- package/ngrok.yml +0 -10
- package/release.config.cjs +0 -15
- package/skills-lock.json +0 -10
- package/types/context-processor.ts +0 -45
- package/types/enums/eval-types.ts +0 -5
- package/types/enums/field-types.ts +0 -1
- package/types/enums/jobs.ts +0 -11
- package/types/enums/statistics.ts +0 -13
- package/types/exulu-table-definition.ts +0 -79
- package/types/file-types.ts +0 -18
- package/types/models/agent-session.ts +0 -27
- package/types/models/agent.ts +0 -68
- package/types/models/context.ts +0 -53
- package/types/models/embedding.ts +0 -17
- package/types/models/eval-run.ts +0 -40
- package/types/models/exulu-agent-tool-config.ts +0 -11
- package/types/models/item.ts +0 -21
- package/types/models/job.ts +0 -8
- package/types/models/project.ts +0 -16
- package/types/models/rate-limiter-rules.ts +0 -7
- package/types/models/test-case.ts +0 -25
- package/types/models/tool.ts +0 -9
- package/types/models/user-role.ts +0 -12
- package/types/models/user.ts +0 -20
- package/types/models/variable.ts +0 -8
- package/types/models/vector-methods.ts +0 -7
- package/types/provider-config.ts +0 -21
- package/types/queue-config.ts +0 -16
- package/types/rbac-rights-modes.ts +0 -1
- package/types/statistics.ts +0 -20
- package/types/workflow.ts +0 -31
- /package/ee/{documents → python/documents}/THIRD_PARTY_LICENSES/docling.txt +0 -0
- /package/ee/{documents/processing → python}/requirements.txt +0 -0
|
@@ -1,650 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Configuration"
|
|
3
|
-
description: "Complete guide to configuring ExuluQueues for background job processing"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
## Queue registration
|
|
7
|
-
|
|
8
|
-
Register queues using the `ExuluQueues.register()` method:
|
|
9
|
-
|
|
10
|
-
```typescript
|
|
11
|
-
ExuluQueues.register(
|
|
12
|
-
name: string,
|
|
13
|
-
concurrency: { worker: number; queue: number },
|
|
14
|
-
ratelimit?: number,
|
|
15
|
-
timeoutInSeconds?: number
|
|
16
|
-
)
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Parameters
|
|
20
|
-
|
|
21
|
-
### name
|
|
22
|
-
|
|
23
|
-
<ParamField path="name" type="string" required>
|
|
24
|
-
Unique queue name. Used to identify the queue and its workers.
|
|
25
|
-
</ParamField>
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
ExuluQueues.register("embeddings", ...)
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
<Note>
|
|
32
|
-
Queue names should be descriptive and unique across your application. Common patterns: `embeddings`, `document-processing`, `data-sync`, `agent-workflows`.
|
|
33
|
-
</Note>
|
|
34
|
-
|
|
35
|
-
### concurrency
|
|
36
|
-
|
|
37
|
-
<ParamField path="concurrency" type="object" required>
|
|
38
|
-
Concurrency configuration with worker and queue levels
|
|
39
|
-
</ParamField>
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
concurrency: {
|
|
43
|
-
worker: number, // Jobs per worker process
|
|
44
|
-
queue: number // Global max jobs across all workers
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
#### concurrency.worker
|
|
49
|
-
|
|
50
|
-
<ParamField path="concurrency.worker" type="number" required>
|
|
51
|
-
Number of jobs a single worker process can handle simultaneously
|
|
52
|
-
</ParamField>
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
concurrency: {
|
|
56
|
-
worker: 5 // Each worker handles 5 jobs at once
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
**Guidelines:**
|
|
61
|
-
- CPU-bound tasks: 1-2 per CPU core
|
|
62
|
-
- I/O-bound tasks: 5-20 per worker
|
|
63
|
-
- Memory-intensive tasks: 1-5 per worker
|
|
64
|
-
|
|
65
|
-
#### concurrency.queue
|
|
66
|
-
|
|
67
|
-
<ParamField path="concurrency.queue" type="number" required>
|
|
68
|
-
Maximum jobs processing globally across all workers
|
|
69
|
-
</ParamField>
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
concurrency: {
|
|
73
|
-
queue: 10 // Max 10 jobs across all workers
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Guidelines:**
|
|
78
|
-
- API rate limits: Match your API's concurrency limit
|
|
79
|
-
- Database load: 5-50 depending on DB capacity
|
|
80
|
-
- External service: Check service documentation
|
|
81
|
-
|
|
82
|
-
### ratelimit
|
|
83
|
-
|
|
84
|
-
<ParamField path="ratelimit" type="number" default={1}>
|
|
85
|
-
Maximum jobs processed per second (default: 1)
|
|
86
|
-
</ParamField>
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
ExuluQueues.register(
|
|
90
|
-
"api-calls",
|
|
91
|
-
{ worker: 5, queue: 10 },
|
|
92
|
-
10 // Process 10 jobs per second
|
|
93
|
-
)
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**Use cases:**
|
|
97
|
-
- API rate limits (e.g., OpenAI: 10 req/sec)
|
|
98
|
-
- Cost control (limit LLM calls per second)
|
|
99
|
-
- Database protection (prevent overload)
|
|
100
|
-
|
|
101
|
-
### timeoutInSeconds
|
|
102
|
-
|
|
103
|
-
<ParamField path="timeoutInSeconds" type="number" default={180}>
|
|
104
|
-
Maximum execution time for a job in seconds (default: 180 = 3 minutes)
|
|
105
|
-
</ParamField>
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
ExuluQueues.register(
|
|
109
|
-
"long-running-tasks",
|
|
110
|
-
{ worker: 2, queue: 5 },
|
|
111
|
-
1,
|
|
112
|
-
600 // 10 minute timeout
|
|
113
|
-
)
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Guidelines:**
|
|
117
|
-
- Quick tasks: 30-60 seconds
|
|
118
|
-
- Document processing: 120-300 seconds
|
|
119
|
-
- Data sync: 300-1800 seconds
|
|
120
|
-
- Large embeddings: 600-3600 seconds
|
|
121
|
-
|
|
122
|
-
## Configuration examples
|
|
123
|
-
|
|
124
|
-
### Embeddings generation queue
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
import { ExuluQueues } from "@exulu/backend";
|
|
128
|
-
|
|
129
|
-
const embeddingsQueue = ExuluQueues.register(
|
|
130
|
-
"embeddings",
|
|
131
|
-
{
|
|
132
|
-
worker: 5, // 5 concurrent embeddings per worker
|
|
133
|
-
queue: 10 // Max 10 embeddings globally
|
|
134
|
-
},
|
|
135
|
-
10, // 10 jobs/second (OpenAI rate limit)
|
|
136
|
-
300 // 5 minute timeout
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
// Use with ExuluEmbedder
|
|
140
|
-
const embedder = new ExuluEmbedder({
|
|
141
|
-
id: "openai_embedder",
|
|
142
|
-
name: "OpenAI Embeddings",
|
|
143
|
-
provider: "openai",
|
|
144
|
-
model: "text-embedding-3-small",
|
|
145
|
-
vectorDimensions: 1536,
|
|
146
|
-
queue: await embeddingsQueue.use()
|
|
147
|
-
});
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Document processing queue
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
const processingQueue = ExuluQueues.register(
|
|
154
|
-
"document-processing",
|
|
155
|
-
{
|
|
156
|
-
worker: 3, // 3 documents per worker
|
|
157
|
-
queue: 5 // Max 5 documents globally
|
|
158
|
-
},
|
|
159
|
-
5, // 5 jobs/second
|
|
160
|
-
600 // 10 minute timeout for large docs
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
// Use with ExuluContext processor
|
|
164
|
-
const context = new ExuluContext({
|
|
165
|
-
id: "documents",
|
|
166
|
-
processor: {
|
|
167
|
-
name: "PDF Text Extractor",
|
|
168
|
-
config: {
|
|
169
|
-
queue: await processingQueue.use(),
|
|
170
|
-
trigger: "onInsert",
|
|
171
|
-
generateEmbeddings: true
|
|
172
|
-
},
|
|
173
|
-
execute: async ({ item, utils }) => {
|
|
174
|
-
const text = await utils.storage.extractText(item.document_s3key);
|
|
175
|
-
return { ...item, content: text };
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Data sync queue
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
const syncQueue = ExuluQueues.register(
|
|
185
|
-
"github-sync",
|
|
186
|
-
{
|
|
187
|
-
worker: 1, // Sequential processing
|
|
188
|
-
queue: 1 // One sync at a time
|
|
189
|
-
},
|
|
190
|
-
1, // 1 job/second (no rush)
|
|
191
|
-
1800 // 30 minute timeout
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
// Use with ExuluContext source
|
|
195
|
-
const context = new ExuluContext({
|
|
196
|
-
id: "github_issues",
|
|
197
|
-
sources: [{
|
|
198
|
-
id: "github",
|
|
199
|
-
name: "GitHub Issues Sync",
|
|
200
|
-
description: "Syncs issues from GitHub",
|
|
201
|
-
config: {
|
|
202
|
-
schedule: "0 */6 * * *", // Every 6 hours
|
|
203
|
-
queue: await syncQueue.use(),
|
|
204
|
-
retries: 3,
|
|
205
|
-
backoff: {
|
|
206
|
-
type: "exponential",
|
|
207
|
-
delay: 2000
|
|
208
|
-
}
|
|
209
|
-
},
|
|
210
|
-
execute: async ({ exuluConfig }) => {
|
|
211
|
-
const issues = await fetchGitHubIssues();
|
|
212
|
-
return issues.map(issue => ({
|
|
213
|
-
external_id: issue.id,
|
|
214
|
-
name: issue.title,
|
|
215
|
-
content: issue.body
|
|
216
|
-
}));
|
|
217
|
-
}
|
|
218
|
-
}]
|
|
219
|
-
});
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### Agent workflow queue
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
const workflowQueue = ExuluQueues.register(
|
|
226
|
-
"agent-workflows",
|
|
227
|
-
{
|
|
228
|
-
worker: 10, // 10 concurrent agent tasks per worker
|
|
229
|
-
queue: 20 // Max 20 agent tasks globally
|
|
230
|
-
},
|
|
231
|
-
20, // 20 jobs/second
|
|
232
|
-
300 // 5 minute timeout
|
|
233
|
-
);
|
|
234
|
-
|
|
235
|
-
// Use with ExuluAgent
|
|
236
|
-
const agent = new ExuluAgent({
|
|
237
|
-
id: "assistant",
|
|
238
|
-
name: "Assistant",
|
|
239
|
-
type: "agent",
|
|
240
|
-
description: "AI assistant",
|
|
241
|
-
provider: "openai",
|
|
242
|
-
config: { /* ... */ },
|
|
243
|
-
workflows: {
|
|
244
|
-
enabled: true,
|
|
245
|
-
queue: await workflowQueue.use()
|
|
246
|
-
},
|
|
247
|
-
capabilities: { text: true, images: [], files: [], audio: [], video: [] }
|
|
248
|
-
});
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### High-throughput queue
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
const highThroughputQueue = ExuluQueues.register(
|
|
255
|
-
"bulk-operations",
|
|
256
|
-
{
|
|
257
|
-
worker: 20, // 20 concurrent jobs per worker
|
|
258
|
-
queue: 100 // Max 100 jobs globally
|
|
259
|
-
},
|
|
260
|
-
50, // 50 jobs/second
|
|
261
|
-
60 // 1 minute timeout
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
// For fast, lightweight operations
|
|
265
|
-
await queueConfig.queue.add("process-item", {
|
|
266
|
-
itemId: "item-123"
|
|
267
|
-
});
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
### Low-throughput, long-running queue
|
|
271
|
-
|
|
272
|
-
```typescript
|
|
273
|
-
const batchQueue = ExuluQueues.register(
|
|
274
|
-
"nightly-batch",
|
|
275
|
-
{
|
|
276
|
-
worker: 1, // Sequential processing
|
|
277
|
-
queue: 1 // One at a time
|
|
278
|
-
},
|
|
279
|
-
0.1, // 1 job every 10 seconds
|
|
280
|
-
7200 // 2 hour timeout
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
// For expensive, long-running batch jobs
|
|
284
|
-
await queueConfig.queue.add("nightly-report", {
|
|
285
|
-
date: new Date()
|
|
286
|
-
});
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
### API-constrained queue
|
|
290
|
-
|
|
291
|
-
```typescript
|
|
292
|
-
// OpenAI has rate limits: 10 req/sec for most tiers
|
|
293
|
-
const openaiQueue = ExuluQueues.register(
|
|
294
|
-
"openai-api",
|
|
295
|
-
{
|
|
296
|
-
worker: 3, // 3 concurrent requests per worker
|
|
297
|
-
queue: 10 // Max 10 requests globally
|
|
298
|
-
},
|
|
299
|
-
9, // 9 req/sec (under the limit)
|
|
300
|
-
120 // 2 minute timeout
|
|
301
|
-
);
|
|
302
|
-
|
|
303
|
-
// Anthropic has different limits: 5 req/sec
|
|
304
|
-
const anthropicQueue = ExuluQueues.register(
|
|
305
|
-
"anthropic-api",
|
|
306
|
-
{
|
|
307
|
-
worker: 2,
|
|
308
|
-
queue: 5
|
|
309
|
-
},
|
|
310
|
-
4, // 4 req/sec (under the limit)
|
|
311
|
-
120
|
|
312
|
-
);
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## Queue configuration object
|
|
316
|
-
|
|
317
|
-
After registration, call `.use()` to get the queue configuration:
|
|
318
|
-
|
|
319
|
-
```typescript
|
|
320
|
-
const myQueue = ExuluQueues.register("my-queue", ...);
|
|
321
|
-
|
|
322
|
-
const config = await myQueue.use();
|
|
323
|
-
|
|
324
|
-
// config has this structure:
|
|
325
|
-
type ExuluQueueConfig = {
|
|
326
|
-
queue: Queue; // BullMQ Queue instance
|
|
327
|
-
ratelimit: number; // Jobs per second
|
|
328
|
-
timeoutInSeconds: number; // Job timeout
|
|
329
|
-
concurrency: {
|
|
330
|
-
worker: number; // Per-worker concurrency
|
|
331
|
-
queue: number; // Global concurrency
|
|
332
|
-
};
|
|
333
|
-
retries?: number; // Retry count (optional)
|
|
334
|
-
backoff?: { // Backoff strategy (optional)
|
|
335
|
-
type: "exponential" | "linear";
|
|
336
|
-
delay: number; // Delay in milliseconds
|
|
337
|
-
};
|
|
338
|
-
};
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
## Retry and backoff configuration
|
|
342
|
-
|
|
343
|
-
Configure retries and backoff in ExuluContext sources:
|
|
344
|
-
|
|
345
|
-
```typescript
|
|
346
|
-
const context = new ExuluContext({
|
|
347
|
-
id: "data",
|
|
348
|
-
sources: [{
|
|
349
|
-
id: "api-source",
|
|
350
|
-
name: "API Data Source",
|
|
351
|
-
description: "Fetches data from external API",
|
|
352
|
-
config: {
|
|
353
|
-
queue: await myQueue.use(),
|
|
354
|
-
retries: 5, // Retry up to 5 times
|
|
355
|
-
backoff: {
|
|
356
|
-
type: "exponential", // exponential or linear
|
|
357
|
-
delay: 1000 // Start with 1 second delay
|
|
358
|
-
}
|
|
359
|
-
},
|
|
360
|
-
execute: async () => {
|
|
361
|
-
const data = await fetchFromAPI();
|
|
362
|
-
return data;
|
|
363
|
-
}
|
|
364
|
-
}]
|
|
365
|
-
});
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
### Exponential backoff
|
|
369
|
-
|
|
370
|
-
Delay doubles after each retry:
|
|
371
|
-
|
|
372
|
-
```typescript
|
|
373
|
-
backoff: {
|
|
374
|
-
type: "exponential",
|
|
375
|
-
delay: 1000 // 1s, 2s, 4s, 8s, 16s, ...
|
|
376
|
-
}
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
**Use for:** Temporary failures, API rate limits, transient network issues
|
|
380
|
-
|
|
381
|
-
### Linear backoff
|
|
382
|
-
|
|
383
|
-
Fixed delay between retries:
|
|
384
|
-
|
|
385
|
-
```typescript
|
|
386
|
-
backoff: {
|
|
387
|
-
type: "linear",
|
|
388
|
-
delay: 5000 // 5s, 5s, 5s, 5s, ...
|
|
389
|
-
}
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
**Use for:** Predictable delays, scheduled retry windows
|
|
393
|
-
|
|
394
|
-
## Concurrency tuning
|
|
395
|
-
|
|
396
|
-
### Start conservative
|
|
397
|
-
|
|
398
|
-
Begin with low concurrency and increase gradually:
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
// Starting point
|
|
402
|
-
ExuluQueues.register(
|
|
403
|
-
"new-queue",
|
|
404
|
-
{ worker: 1, queue: 1 }, // Start with 1
|
|
405
|
-
1,
|
|
406
|
-
180
|
|
407
|
-
);
|
|
408
|
-
|
|
409
|
-
// After testing, increase
|
|
410
|
-
ExuluQueues.register(
|
|
411
|
-
"new-queue",
|
|
412
|
-
{ worker: 5, queue: 10 }, // Scale up
|
|
413
|
-
10,
|
|
414
|
-
180
|
|
415
|
-
);
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
### Monitor and adjust
|
|
419
|
-
|
|
420
|
-
Watch these metrics:
|
|
421
|
-
- **CPU usage**: High CPU? Reduce worker concurrency
|
|
422
|
-
- **Memory usage**: High memory? Reduce worker concurrency
|
|
423
|
-
- **Queue depth**: Jobs piling up? Increase concurrency
|
|
424
|
-
- **Error rate**: Many failures? Reduce concurrency or rate limit
|
|
425
|
-
|
|
426
|
-
### Concurrency patterns
|
|
427
|
-
|
|
428
|
-
<Tabs>
|
|
429
|
-
<Tab title="Balanced">
|
|
430
|
-
```typescript
|
|
431
|
-
// Good for general-purpose queues
|
|
432
|
-
concurrency: {
|
|
433
|
-
worker: 5, // Moderate per-worker
|
|
434
|
-
queue: 20 // Higher global limit
|
|
435
|
-
}
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
Multiple workers can run without hitting global limit.
|
|
439
|
-
</Tab>
|
|
440
|
-
|
|
441
|
-
<Tab title="Worker-heavy">
|
|
442
|
-
```typescript
|
|
443
|
-
// Good for I/O-bound tasks with no global constraints
|
|
444
|
-
concurrency: {
|
|
445
|
-
worker: 20, // High per-worker
|
|
446
|
-
queue: 1000 // Very high global limit
|
|
447
|
-
}
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
Workers max out before hitting global limit.
|
|
451
|
-
</Tab>
|
|
452
|
-
|
|
453
|
-
<Tab title="Queue-constrained">
|
|
454
|
-
```typescript
|
|
455
|
-
// Good for external API rate limits
|
|
456
|
-
concurrency: {
|
|
457
|
-
worker: 2, // Low per-worker
|
|
458
|
-
queue: 10 // Strict global limit
|
|
459
|
-
}
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
Global limit enforced across all workers.
|
|
463
|
-
</Tab>
|
|
464
|
-
|
|
465
|
-
<Tab title="Sequential">
|
|
466
|
-
```typescript
|
|
467
|
-
// Good for ordered processing or single-threaded tasks
|
|
468
|
-
concurrency: {
|
|
469
|
-
worker: 1,
|
|
470
|
-
queue: 1
|
|
471
|
-
}
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
One job at a time, guaranteed order.
|
|
475
|
-
</Tab>
|
|
476
|
-
</Tabs>
|
|
477
|
-
|
|
478
|
-
## Rate limit strategies
|
|
479
|
-
|
|
480
|
-
### API-based
|
|
481
|
-
|
|
482
|
-
Match your API provider's limits:
|
|
483
|
-
|
|
484
|
-
```typescript
|
|
485
|
-
// OpenAI Tier 4: 10,000 req/min = 166 req/sec
|
|
486
|
-
ExuluQueues.register("openai", { worker: 10, queue: 100 }, 150);
|
|
487
|
-
|
|
488
|
-
// Anthropic Pro: 5 req/sec
|
|
489
|
-
ExuluQueues.register("anthropic", { worker: 2, queue: 5 }, 4);
|
|
490
|
-
|
|
491
|
-
// Google Gemini: 60 req/min = 1 req/sec
|
|
492
|
-
ExuluQueues.register("gemini", { worker: 1, queue: 1 }, 0.9);
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
### Cost-based
|
|
496
|
-
|
|
497
|
-
Control spending by limiting throughput:
|
|
498
|
-
|
|
499
|
-
```typescript
|
|
500
|
-
// Limit expensive LLM calls
|
|
501
|
-
ExuluQueues.register(
|
|
502
|
-
"gpt4-calls",
|
|
503
|
-
{ worker: 1, queue: 2 },
|
|
504
|
-
0.5 // 0.5 jobs/sec = 1800 calls/hour
|
|
505
|
-
);
|
|
506
|
-
|
|
507
|
-
// Track costs:
|
|
508
|
-
// 1800 calls/hr × $0.03/call = $54/hr max
|
|
509
|
-
```
|
|
510
|
-
|
|
511
|
-
### Database-based
|
|
512
|
-
|
|
513
|
-
Prevent database overload:
|
|
514
|
-
|
|
515
|
-
```typescript
|
|
516
|
-
// PostgreSQL can handle ~100-200 concurrent connections
|
|
517
|
-
ExuluQueues.register(
|
|
518
|
-
"db-queries",
|
|
519
|
-
{ worker: 10, queue: 50 },
|
|
520
|
-
100 // 100 queries/sec
|
|
521
|
-
);
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
## Timeout configuration
|
|
525
|
-
|
|
526
|
-
Set timeouts based on expected duration + buffer:
|
|
527
|
-
|
|
528
|
-
```typescript
|
|
529
|
-
// Quick operations (embeddings)
|
|
530
|
-
ExuluQueues.register("embeddings", { ... }, 10, 60); // 1 min
|
|
531
|
-
|
|
532
|
-
// Medium operations (document parsing)
|
|
533
|
-
ExuluQueues.register("parsing", { ... }, 5, 300); // 5 min
|
|
534
|
-
|
|
535
|
-
// Long operations (data sync)
|
|
536
|
-
ExuluQueues.register("sync", { ... }, 1, 1800); // 30 min
|
|
537
|
-
|
|
538
|
-
// Very long operations (large batch jobs)
|
|
539
|
-
ExuluQueues.register("batch", { ... }, 1, 7200); // 2 hours
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
<Warning>
|
|
543
|
-
Jobs that exceed the timeout are terminated and marked as failed. Ensure timeouts are realistic for your workload.
|
|
544
|
-
</Warning>
|
|
545
|
-
|
|
546
|
-
## Redis configuration
|
|
547
|
-
|
|
548
|
-
ExuluQueues requires Redis connection information:
|
|
549
|
-
|
|
550
|
-
```bash
|
|
551
|
-
# .env file
|
|
552
|
-
REDIS_HOST=localhost
|
|
553
|
-
REDIS_PORT=6379
|
|
554
|
-
REDIS_PASSWORD=your-password # Optional
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
Or configure programmatically:
|
|
558
|
-
|
|
559
|
-
```typescript
|
|
560
|
-
import { redisServer } from "@exulu/backend";
|
|
561
|
-
|
|
562
|
-
redisServer.host = "localhost";
|
|
563
|
-
redisServer.port = "6379";
|
|
564
|
-
redisServer.password = "your-password"; // Optional
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
### Redis for production
|
|
568
|
-
|
|
569
|
-
For production environments:
|
|
570
|
-
|
|
571
|
-
```bash
|
|
572
|
-
# Managed Redis service
|
|
573
|
-
REDIS_HOST=redis-12345.cloud.redislabs.com
|
|
574
|
-
REDIS_PORT=12345
|
|
575
|
-
REDIS_PASSWORD=your-secure-password
|
|
576
|
-
```
|
|
577
|
-
|
|
578
|
-
Recommended providers:
|
|
579
|
-
- Redis Cloud
|
|
580
|
-
- AWS ElastiCache
|
|
581
|
-
- Google Cloud Memorystore
|
|
582
|
-
- Azure Cache for Redis
|
|
583
|
-
|
|
584
|
-
## Best practices
|
|
585
|
-
|
|
586
|
-
<AccordionGroup>
|
|
587
|
-
<Accordion title="One queue per purpose">
|
|
588
|
-
Create separate queues for different workload types:
|
|
589
|
-
|
|
590
|
-
```typescript
|
|
591
|
-
ExuluQueues.register("embeddings", ...);
|
|
592
|
-
ExuluQueues.register("processing", ...);
|
|
593
|
-
ExuluQueues.register("sync", ...);
|
|
594
|
-
```
|
|
595
|
-
|
|
596
|
-
Benefits: Independent scaling, better monitoring, isolated failures
|
|
597
|
-
</Accordion>
|
|
598
|
-
|
|
599
|
-
<Accordion title="Match concurrency to resources">
|
|
600
|
-
Consider available CPU, memory, and external service limits:
|
|
601
|
-
|
|
602
|
-
```typescript
|
|
603
|
-
// 4 CPU cores → worker concurrency 4-8
|
|
604
|
-
// 8 GB RAM → adjust based on job memory
|
|
605
|
-
// API limit 10 req/sec → rate limit 9
|
|
606
|
-
```
|
|
607
|
-
</Accordion>
|
|
608
|
-
|
|
609
|
-
<Accordion title="Set realistic timeouts">
|
|
610
|
-
Add buffer to expected duration:
|
|
611
|
-
|
|
612
|
-
```typescript
|
|
613
|
-
// Expected: 30 seconds → Timeout: 60 seconds
|
|
614
|
-
// Expected: 2 minutes → Timeout: 5 minutes
|
|
615
|
-
```
|
|
616
|
-
</Accordion>
|
|
617
|
-
|
|
618
|
-
<Accordion title="Use exponential backoff">
|
|
619
|
-
For transient failures, exponential backoff is more effective:
|
|
620
|
-
|
|
621
|
-
```typescript
|
|
622
|
-
backoff: {
|
|
623
|
-
type: "exponential",
|
|
624
|
-
delay: 1000 // 1s, 2s, 4s, 8s, 16s
|
|
625
|
-
}
|
|
626
|
-
```
|
|
627
|
-
</Accordion>
|
|
628
|
-
|
|
629
|
-
<Accordion title="Monitor queue depth">
|
|
630
|
-
If jobs pile up (high waiting count), increase concurrency or rate limit:
|
|
631
|
-
|
|
632
|
-
```typescript
|
|
633
|
-
const counts = await config.queue.getJobCounts();
|
|
634
|
-
if (counts.waiting > 1000) {
|
|
635
|
-
// Consider increasing concurrency
|
|
636
|
-
}
|
|
637
|
-
```
|
|
638
|
-
</Accordion>
|
|
639
|
-
</AccordionGroup>
|
|
640
|
-
|
|
641
|
-
## Next steps
|
|
642
|
-
|
|
643
|
-
<CardGroup cols={2}>
|
|
644
|
-
<Card title="API reference" icon="code" href="/core/exulu-queues/api-reference">
|
|
645
|
-
Explore methods and properties
|
|
646
|
-
</Card>
|
|
647
|
-
<Card title="ExuluContext" icon="database" href="/core/exulu-context/introduction">
|
|
648
|
-
Learn how contexts use queues
|
|
649
|
-
</Card>
|
|
650
|
-
</CardGroup>
|