thefinalboss commited on
Commit
7eb3e6a
·
verified ·
1 Parent(s): 39366f4

Add AICL example: 23_decorator_pipeline.aicl

Browse files
data/aicl/examples/23_decorator_pipeline.aicl ADDED
@@ -0,0 +1,469 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AICL Example: Decorator Pattern Pipeline
2
+ # Implements a decorator pattern pipeline for middleware chains, request/response filters,
3
+ # and cross-cutting concerns like logging, authentication, rate limiting, caching, and compression.
4
+
5
+ # Level 1: Architecture
6
+ Goal: Build a decorator pattern pipeline that composes middleware chains for request processing,
7
+ applies request and response filters for cross-cutting concerns, supports ordering and
8
+ conditional activation of decorators, and enables transparent addition of behaviors without
9
+ modifying core business logic.
10
+
11
+ Constraint: Each decorator must have a single responsibility and not mix concerns.
12
+ Constraint: Decorator order must be explicitly declared; implicit ordering is forbidden.
13
+ Constraint: A decorator must not swallow exceptions from inner handlers without re-raising or wrapping.
14
+ Constraint: Pipeline must support both request and response decoration phases.
15
+ Constraint: Each decorator must be independently testable without the full pipeline.
16
+
17
+ Risk: Decorator order sensitivity causes subtle bugs
18
+ Recovery: Document order dependencies; validate ordering constraints at pipeline construction time
19
+
20
+ Risk: Exception in decorator leaves pipeline in partial state
21
+ Recovery: Execute response decorators in reverse order on error path; ensure cleanup decorators run always
22
+
23
+ Risk: Performance overhead from deep decorator nesting
24
+ Recovery: Profile pipeline latency per decorator; collapse trivial decorators; add short-circuit option
25
+
26
+ Risk: Decorator side effects leak between requests
27
+ Recovery: Enforce per-request decorator state isolation; detect shared mutable state at registration
28
+
29
+ Risk: Missing decorator causes silent feature gap
30
+ Recovery: Declare required decorators per route; fail at startup if required decorator is missing
31
+
32
+ Risk: Decorator configuration drift across environments
33
+ Recovery: Version pipeline configurations; validate deployed configuration matches declared schema
34
+
35
+ Layer: Pipeline
36
+ SubLayer: PipelineBuilder
37
+ SubLayer: PipelineExecutor
38
+ SubLayer: DecoratorChain
39
+ Layer: Decorators
40
+ SubLayer: AuthenticationDecorator
41
+ SubLayer: RateLimitDecorator
42
+ SubLayer: LoggingDecorator
43
+ SubLayer: CachingDecorator
44
+ SubLayer: CompressionDecorator
45
+ Layer: Core
46
+ SubLayer: RequestHandler
47
+ SubLayer: ResponseProcessor
48
+ SubLayer: ErrorHandler
49
+
50
+ Validation: Each decorator must implement before and after hooks
51
+ Validation: Pipeline must contain at least one terminal handler
52
+ Validation: Decorator ordering must satisfy declared dependency constraints
53
+ Validation: No decorator may modify the request object in place; must return new instance
54
+ Validation: Pipeline execution time must not exceed configured maximum
55
+ Validation: Error handler decorator must be present in every pipeline
56
+
57
+ # Level 2: Entities
58
+ Entity Pipeline
59
+ pipelineId: string
60
+ name: string
61
+ decorators: list
62
+ terminalHandler: string
63
+ maxExecutionTime: integer
64
+ createdAt: datetime
65
+ version: string
66
+ isActive: boolean
67
+
68
+ Entity Decorator
69
+ decoratorId: string
70
+ decoratorName: string
71
+ decoratorType: string
72
+ order: integer
73
+ isRequired: boolean
74
+ config: dict
75
+ isActive: boolean
76
+ appliesTo: list
77
+ dependencies: list
78
+
79
+ Entity RequestContext
80
+ requestId: string
81
+ method: string
82
+ path: string
83
+ headers: dict
84
+ body: any
85
+ queryParams: dict
86
+ attributes: dict
87
+ startTime: datetime
88
+ userId: string
89
+
90
+ Entity ResponseContext
91
+ requestId: string
92
+ statusCode: integer
93
+ headers: dict
94
+ body: any
95
+ attributes: dict
96
+ processingTime: integer
97
+ decoratorTrail: list
98
+ cacheHit: boolean
99
+
100
+ Entity DecoratorResult
101
+ decoratorId: string
102
+ phase: string
103
+ duration: integer
104
+ modified: boolean
105
+ shortCircuited: boolean
106
+ error: string
107
+ timestamp: datetime
108
+
109
+ Entity PipelineExecution
110
+ executionId: string
111
+ pipelineId: string
112
+ requestId: string
113
+ startedAt: datetime
114
+ completedAt: datetime
115
+ totalDuration: integer
116
+ decoratorResults: list
117
+ finalStatus: string
118
+ errorDecorator: string
119
+
120
+ # Level 3: Behaviors
121
+ Behavior BuildPipeline
122
+ Input:
123
+ name: string
124
+ decoratorConfigs: list
125
+ terminalHandler: string
126
+ Output:
127
+ pipelineId: string
128
+ Action:
129
+ Validate all decorator configurations
130
+ Resolve decorator dependencies and validate availability
131
+ Sort decorators by declared order with dependency resolution
132
+ Check for circular dependencies between decorators
133
+ Validate terminal handler exists
134
+ Register pipeline with version stamp
135
+ Return pipeline identifier
136
+
137
+ Behavior ExecutePipeline
138
+ Input:
139
+ pipeline: Pipeline
140
+ request: RequestContext
141
+ Output:
142
+ response: ResponseContext
143
+ Action:
144
+ Initialize execution tracking
145
+ Execute request phase of each decorator in order
146
+ If any decorator short-circuits, skip remaining request decorators
147
+ Invoke terminal handler with decorated request
148
+ Execute response phase of each decorator in reverse order
149
+ Handle errors by delegating to error handler decorator
150
+ Collect timing and modification data from each decorator
151
+ Return final decorated response
152
+
153
+ Behavior ApplyDecorator
154
+ Input:
155
+ decorator: Decorator
156
+ context: any
157
+ phase: string
158
+ Output:
159
+ result: DecoratorResult
160
+ modifiedContext: any
161
+ Action:
162
+ Check decorator activation condition against context
163
+ If inactive, pass through without modification
164
+ Execute decorator logic for specified phase
165
+ Track whether context was modified
166
+ Handle decorator-specific errors gracefully
167
+ Return decorator result and modified context
168
+
169
+ Behavior ShortCircuit
170
+ Input:
171
+ decorator: Decorator
172
+ response: ResponseContext
173
+ reason: string
174
+ Output:
175
+ response: ResponseContext
176
+ Action:
177
+ Set short-circuit flag on decorator result
178
+ Skip remaining request-phase decorators
179
+ Begin response phase from short-circuit point
180
+ Add short-circuit reason to response attributes
181
+ Return immediate response
182
+
183
+ Behavior HandlePipelineError
184
+ Input:
185
+ pipeline: Pipeline
186
+ failedDecorator: string
187
+ error: string
188
+ request: RequestContext
189
+ Output:
190
+ errorResponse: ResponseContext
191
+ Action:
192
+ Log error with full decorator trail
193
+ Execute cleanup phase for decorators that ran before failure
194
+ Apply error handler decorator to produce user-facing response
195
+ Record error in pipeline execution metrics
196
+ Ensure no decorator state leaks to error response
197
+ Return sanitized error response
198
+
199
+ Behavior ComposeDecorators
200
+ Input:
201
+ first: Decorator
202
+ second: Decorator
203
+ Output:
204
+ composed: Decorator
205
+ Action:
206
+ Merge configuration of both decorators
207
+ Compose before-hook as second then first
208
+ Compose after-hook as first then second
209
+ Resolve order conflicts with priority rule
210
+ Register composed decorator with merged metadata
211
+ Return composed decorator reference
212
+
213
+ # Level 4: Conditions
214
+ Condition: RateLimitExceeded
215
+ When rate limit decorator detects request count exceeds threshold
216
+ Then short-circuit with HTTP 429 and include retry-after header
217
+
218
+ Condition: AuthenticationFailed
219
+ When authentication decorator cannot validate credentials
220
+ Then short-circuit with HTTP 401 and terminate pipeline without reaching handler
221
+
222
+ Condition: CacheHitOnRead
223
+ When caching decorator finds valid cached response for request
224
+ Then short-circuit with cached response; skip terminal handler entirely
225
+
226
+ # Level 5: Events
227
+ Event: OnPipelineBuilt
228
+ On new pipeline assembled and validated
229
+ Action: Log pipeline composition, warm decorator instances, verify all dependencies met
230
+
231
+ Event: OnDecoratorShortCircuit
232
+ On decorator triggers short-circuit during request phase
233
+ Action: Record which decorator short-circuited and why; update pipeline metrics
234
+
235
+ Event: OnPipelineError
236
+ On unhandled exception during pipeline execution
237
+ Action: Alert on-call, increment error metric, preserve request context for debugging
238
+
239
+ Event: OnDecoratorAdded
240
+ On new decorator registered in the system
241
+ Action: Validate decorator contract compliance, add to decorator catalog, test in isolation
242
+
243
+ # Level 6: Concurrency
244
+ Parallel:
245
+ Independent pipeline executions for different requests
246
+ Decorator activation condition evaluation
247
+ Caching decorator lookup against distributed cache
248
+ Rate limit counter updates with atomic increments
249
+ Pipeline metric aggregation from all execution threads
250
+
251
+ # Level 7: Optimization
252
+ Optimize: Pipeline execution latency
253
+ Priority: Short-circuit expensive decorators early; cache decorator activation evaluation results
254
+
255
+ Optimize: Decorator instantiation overhead
256
+ Priority: Pool decorator instances; reuse across requests; lazy-initialize expensive resources
257
+
258
+ # Level 8: Learning
259
+ Learn: Optimal decorator ordering
260
+ Goal: Minimize average pipeline latency by reordering decorators based on short-circuit frequency
261
+ Adapt: Decorator order within dependency constraints
262
+ Based: Short-circuit rate per decorator and cost of executing each decorator
263
+
264
+ Learn: Cache effectiveness per route
265
+ Goal: Maximize cache hit ratio while minimizing memory usage
266
+ Adapt: Caching decorator TTL and cacheable routes per method-path pattern
267
+ Based: Cache hit ratio, response size, and request frequency per route
268
+
269
+ # Level 9: Security
270
+ Security:
271
+ Encrypt: Request bodies containing sensitive data as they pass through decorator pipeline
272
+ Encrypt: Decorator configuration secrets using vault-backed encrypted config
273
+ Protect: Authentication decorator tokens with short-lived JWT and rotation
274
+ Protect: Rate limit state from manipulation via signed counters stored in secure backend
275
+ Protect: Pipeline from decorator injection by validating decorator signatures at registration
276
+
277
+ # Level 10: Native
278
+ TypeScript
279
+ {
280
+ type RequestPhase = 'before' | 'after';
281
+ type Next = () => Promise<ResponseContext>;
282
+
283
+ interface RequestContext {
284
+ requestId: string;
285
+ method: string;
286
+ path: string;
287
+ headers: Record<string, string>;
288
+ body: any;
289
+ queryParams: Record<string, string>;
290
+ attributes: Record<string, any>;
291
+ startTime: Date;
292
+ userId?: string;
293
+ }
294
+
295
+ interface ResponseContext {
296
+ requestId: string;
297
+ statusCode: number;
298
+ headers: Record<string, string>;
299
+ body: any;
300
+ attributes: Record<string, any>;
301
+ processingTime: number;
302
+ decoratorTrail: string[];
303
+ cacheHit: boolean;
304
+ }
305
+
306
+ interface Decorator {
307
+ name: string;
308
+ order: number;
309
+ before?: (req: RequestContext, next: Next) => Promise<ResponseContext>;
310
+ after?: (req: RequestContext, res: ResponseContext) => Promise<ResponseContext>;
311
+ isActive: (req: RequestContext) => boolean;
312
+ }
313
+
314
+ class Pipeline {
315
+ private decorators: Decorator[] = [];
316
+ private terminalHandler: (req: RequestContext) => Promise<ResponseContext>;
317
+
318
+ constructor(terminalHandler: (req: RequestContext) => Promise<ResponseContext>) {
319
+ this.terminalHandler = terminalHandler;
320
+ }
321
+
322
+ use(decorator: Decorator): Pipeline {
323
+ this.decorators.push(decorator);
324
+ this.decorators.sort((a, b) => a.order - b.order);
325
+ return this;
326
+ }
327
+
328
+ async execute(request: RequestContext): Promise<ResponseContext> {
329
+ const trail: string[] = [];
330
+ const startTime = Date.now();
331
+
332
+ const buildChain = (index: number): Next => {
333
+ return async (): Promise<ResponseContext> => {
334
+ if (index >= this.decorators.length) {
335
+ const response = await this.terminalHandler(request);
336
+ return {
337
+ requestId: request.requestId,
338
+ statusCode: response.statusCode,
339
+ headers: response.headers,
340
+ body: response.body,
341
+ attributes: {},
342
+ processingTime: Date.now() - startTime,
343
+ decoratorTrail: trail,
344
+ cacheHit: false,
345
+ };
346
+ }
347
+
348
+ const decorator = this.decorators[index];
349
+ if (!decorator.isActive(request)) {
350
+ return buildChain(index + 1)();
351
+ }
352
+
353
+ trail.push(decorator.name);
354
+
355
+ if (decorator.before) {
356
+ return decorator.before(request, buildChain(index + 1));
357
+ }
358
+ return buildChain(index + 1)();
359
+ };
360
+ };
361
+
362
+ let response = await buildChain(0)();
363
+
364
+ for (let i = this.decorators.length - 1; i >= 0; i--) {
365
+ const decorator = this.decorators[i];
366
+ if (decorator.after && decorator.isActive(request)) {
367
+ response = await decorator.after(request, response);
368
+ }
369
+ }
370
+
371
+ return response;
372
+ }
373
+ }
374
+
375
+ const loggingDecorator: Decorator = {
376
+ name: 'logging',
377
+ order: 0,
378
+ before: async (req, next) => {
379
+ console.log(`[${req.requestId}] --> ${req.method} ${req.path}`);
380
+ const res = await next();
381
+ console.log(`[${req.requestId}] <-- ${res.statusCode}`);
382
+ return res;
383
+ },
384
+ isActive: () => true,
385
+ };
386
+
387
+ const authDecorator: Decorator = {
388
+ name: 'authentication',
389
+ order: 10,
390
+ before: async (req, next) => {
391
+ const token = req.headers['authorization'];
392
+ if (!token) {
393
+ return {
394
+ requestId: req.requestId,
395
+ statusCode: 401,
396
+ headers: {},
397
+ body: { error: 'Unauthorized' },
398
+ attributes: {},
399
+ processingTime: 0,
400
+ decoratorTrail: [],
401
+ cacheHit: false,
402
+ };
403
+ }
404
+ req.userId = token.replace('Bearer ', '');
405
+ return next();
406
+ },
407
+ isActive: (req) => !req.path.startsWith('/public'),
408
+ };
409
+
410
+ const rateLimitDecorator: Decorator = {
411
+ name: 'rate-limit',
412
+ order: 5,
413
+ before: async (req, next) => {
414
+ const count = rateLimitCounter.increment(req.attributes['clientIp'] as string);
415
+ if (count > 100) {
416
+ return {
417
+ requestId: req.requestId,
418
+ statusCode: 429,
419
+ headers: { 'retry-after': '60' },
420
+ body: { error: 'Rate limit exceeded' },
421
+ attributes: {},
422
+ processingTime: 0,
423
+ decoratorTrail: [],
424
+ cacheHit: false,
425
+ };
426
+ }
427
+ return next();
428
+ },
429
+ isActive: () => true,
430
+ };
431
+
432
+ class RateLimitCounter {
433
+ private counts = new Map<string, number>();
434
+ increment(key: string): number {
435
+ const current = (this.counts.get(key) || 0) + 1;
436
+ this.counts.set(key, current);
437
+ return current;
438
+ }
439
+ }
440
+
441
+ const rateLimitCounter = new RateLimitCounter();
442
+
443
+ async function handler(req: RequestContext): Promise<ResponseContext> {
444
+ return {
445
+ requestId: req.requestId,
446
+ statusCode: 200,
447
+ headers: { 'content-type': 'application/json' },
448
+ body: { message: 'Hello', userId: req.userId },
449
+ attributes: {},
450
+ processingTime: 0,
451
+ decoratorTrail: [],
452
+ cacheHit: false,
453
+ };
454
+ }
455
+
456
+ const pipeline = new Pipeline(handler)
457
+ .use(loggingDecorator)
458
+ .use(rateLimitDecorator)
459
+ .use(authDecorator);
460
+
461
+ const req: RequestContext = {
462
+ requestId: 'req-1', method: 'GET', path: '/api/data',
463
+ headers: { authorization: 'Bearer user-123' },
464
+ body: null, queryParams: {}, attributes: { clientIp: '10.0.0.1' },
465
+ startTime: new Date(),
466
+ };
467
+
468
+ pipeline.execute(req).then(res => console.log('Response:', res.statusCode, res.body));
469
+ }