@dojocho/effect-ts 0.0.1

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.
Files changed (149) hide show
  1. package/DOJO.md +22 -0
  2. package/dojo.json +50 -0
  3. package/katas/001-hello-effect/SENSEI.md +72 -0
  4. package/katas/001-hello-effect/solution.test.ts +35 -0
  5. package/katas/001-hello-effect/solution.ts +16 -0
  6. package/katas/002-transform-with-map/SENSEI.md +72 -0
  7. package/katas/002-transform-with-map/solution.test.ts +33 -0
  8. package/katas/002-transform-with-map/solution.ts +16 -0
  9. package/katas/003-generator-pipelines/SENSEI.md +72 -0
  10. package/katas/003-generator-pipelines/solution.test.ts +40 -0
  11. package/katas/003-generator-pipelines/solution.ts +29 -0
  12. package/katas/004-flatmap-and-chaining/SENSEI.md +80 -0
  13. package/katas/004-flatmap-and-chaining/solution.test.ts +34 -0
  14. package/katas/004-flatmap-and-chaining/solution.ts +18 -0
  15. package/katas/005-pipe-composition/SENSEI.md +81 -0
  16. package/katas/005-pipe-composition/solution.test.ts +41 -0
  17. package/katas/005-pipe-composition/solution.ts +19 -0
  18. package/katas/006-handle-errors/SENSEI.md +86 -0
  19. package/katas/006-handle-errors/solution.test.ts +53 -0
  20. package/katas/006-handle-errors/solution.ts +30 -0
  21. package/katas/007-tagged-errors/SENSEI.md +79 -0
  22. package/katas/007-tagged-errors/solution.test.ts +82 -0
  23. package/katas/007-tagged-errors/solution.ts +37 -0
  24. package/katas/008-error-patterns/SENSEI.md +89 -0
  25. package/katas/008-error-patterns/solution.test.ts +41 -0
  26. package/katas/008-error-patterns/solution.ts +38 -0
  27. package/katas/009-option-type/SENSEI.md +96 -0
  28. package/katas/009-option-type/solution.test.ts +49 -0
  29. package/katas/009-option-type/solution.ts +26 -0
  30. package/katas/010-either-and-exit/SENSEI.md +86 -0
  31. package/katas/010-either-and-exit/solution.test.ts +33 -0
  32. package/katas/010-either-and-exit/solution.ts +17 -0
  33. package/katas/011-services-and-context/SENSEI.md +82 -0
  34. package/katas/011-services-and-context/solution.test.ts +23 -0
  35. package/katas/011-services-and-context/solution.ts +17 -0
  36. package/katas/012-layers/SENSEI.md +73 -0
  37. package/katas/012-layers/solution.test.ts +23 -0
  38. package/katas/012-layers/solution.ts +26 -0
  39. package/katas/013-testing-effects/SENSEI.md +88 -0
  40. package/katas/013-testing-effects/solution.test.ts +41 -0
  41. package/katas/013-testing-effects/solution.ts +20 -0
  42. package/katas/014-schema-basics/SENSEI.md +81 -0
  43. package/katas/014-schema-basics/solution.test.ts +35 -0
  44. package/katas/014-schema-basics/solution.ts +25 -0
  45. package/katas/015-domain-modeling/SENSEI.md +85 -0
  46. package/katas/015-domain-modeling/solution.test.ts +46 -0
  47. package/katas/015-domain-modeling/solution.ts +42 -0
  48. package/katas/016-retry-and-schedule/SENSEI.md +72 -0
  49. package/katas/016-retry-and-schedule/solution.test.ts +26 -0
  50. package/katas/016-retry-and-schedule/solution.ts +23 -0
  51. package/katas/017-parallel-effects/SENSEI.md +70 -0
  52. package/katas/017-parallel-effects/solution.test.ts +33 -0
  53. package/katas/017-parallel-effects/solution.ts +17 -0
  54. package/katas/018-race-and-timeout/SENSEI.md +75 -0
  55. package/katas/018-race-and-timeout/solution.test.ts +30 -0
  56. package/katas/018-race-and-timeout/solution.ts +27 -0
  57. package/katas/019-ref-and-state/SENSEI.md +72 -0
  58. package/katas/019-ref-and-state/solution.test.ts +29 -0
  59. package/katas/019-ref-and-state/solution.ts +16 -0
  60. package/katas/020-fibers/SENSEI.md +80 -0
  61. package/katas/020-fibers/solution.test.ts +23 -0
  62. package/katas/020-fibers/solution.ts +23 -0
  63. package/katas/021-acquire-release/SENSEI.md +57 -0
  64. package/katas/021-acquire-release/solution.test.ts +23 -0
  65. package/katas/021-acquire-release/solution.ts +22 -0
  66. package/katas/022-scoped-layers/SENSEI.md +52 -0
  67. package/katas/022-scoped-layers/solution.test.ts +35 -0
  68. package/katas/022-scoped-layers/solution.ts +19 -0
  69. package/katas/023-resource-patterns/SENSEI.md +52 -0
  70. package/katas/023-resource-patterns/solution.test.ts +20 -0
  71. package/katas/023-resource-patterns/solution.ts +13 -0
  72. package/katas/024-streams-basics/SENSEI.md +61 -0
  73. package/katas/024-streams-basics/solution.test.ts +30 -0
  74. package/katas/024-streams-basics/solution.ts +16 -0
  75. package/katas/025-stream-operations/SENSEI.md +59 -0
  76. package/katas/025-stream-operations/solution.test.ts +26 -0
  77. package/katas/025-stream-operations/solution.ts +17 -0
  78. package/katas/026-combining-streams/SENSEI.md +54 -0
  79. package/katas/026-combining-streams/solution.test.ts +20 -0
  80. package/katas/026-combining-streams/solution.ts +16 -0
  81. package/katas/027-data-pipelines/SENSEI.md +58 -0
  82. package/katas/027-data-pipelines/solution.test.ts +22 -0
  83. package/katas/027-data-pipelines/solution.ts +16 -0
  84. package/katas/028-logging-and-spans/SENSEI.md +58 -0
  85. package/katas/028-logging-and-spans/solution.test.ts +50 -0
  86. package/katas/028-logging-and-spans/solution.ts +20 -0
  87. package/katas/029-http-client/SENSEI.md +59 -0
  88. package/katas/029-http-client/solution.test.ts +49 -0
  89. package/katas/029-http-client/solution.ts +24 -0
  90. package/katas/030-capstone/SENSEI.md +63 -0
  91. package/katas/030-capstone/solution.test.ts +67 -0
  92. package/katas/030-capstone/solution.ts +55 -0
  93. package/katas/031-config-and-environment/SENSEI.md +77 -0
  94. package/katas/031-config-and-environment/solution.test.ts +38 -0
  95. package/katas/031-config-and-environment/solution.ts +11 -0
  96. package/katas/032-cause-and-defects/SENSEI.md +90 -0
  97. package/katas/032-cause-and-defects/solution.test.ts +50 -0
  98. package/katas/032-cause-and-defects/solution.ts +23 -0
  99. package/katas/033-pattern-matching/SENSEI.md +86 -0
  100. package/katas/033-pattern-matching/solution.test.ts +36 -0
  101. package/katas/033-pattern-matching/solution.ts +28 -0
  102. package/katas/034-deferred-and-coordination/SENSEI.md +85 -0
  103. package/katas/034-deferred-and-coordination/solution.test.ts +25 -0
  104. package/katas/034-deferred-and-coordination/solution.ts +24 -0
  105. package/katas/035-queue-and-backpressure/SENSEI.md +100 -0
  106. package/katas/035-queue-and-backpressure/solution.test.ts +25 -0
  107. package/katas/035-queue-and-backpressure/solution.ts +21 -0
  108. package/katas/036-schema-advanced/SENSEI.md +81 -0
  109. package/katas/036-schema-advanced/solution.test.ts +55 -0
  110. package/katas/036-schema-advanced/solution.ts +19 -0
  111. package/katas/037-cache-and-memoization/SENSEI.md +73 -0
  112. package/katas/037-cache-and-memoization/solution.test.ts +47 -0
  113. package/katas/037-cache-and-memoization/solution.ts +24 -0
  114. package/katas/038-metrics/SENSEI.md +91 -0
  115. package/katas/038-metrics/solution.test.ts +39 -0
  116. package/katas/038-metrics/solution.ts +23 -0
  117. package/katas/039-managed-runtime/SENSEI.md +75 -0
  118. package/katas/039-managed-runtime/solution.test.ts +29 -0
  119. package/katas/039-managed-runtime/solution.ts +19 -0
  120. package/katas/040-request-batching/SENSEI.md +87 -0
  121. package/katas/040-request-batching/solution.test.ts +56 -0
  122. package/katas/040-request-batching/solution.ts +32 -0
  123. package/package.json +22 -0
  124. package/skills/effect-patterns-building-apis/SKILL.md +2393 -0
  125. package/skills/effect-patterns-building-data-pipelines/SKILL.md +1876 -0
  126. package/skills/effect-patterns-concurrency/SKILL.md +2999 -0
  127. package/skills/effect-patterns-concurrency-getting-started/SKILL.md +351 -0
  128. package/skills/effect-patterns-core-concepts/SKILL.md +3199 -0
  129. package/skills/effect-patterns-domain-modeling/SKILL.md +1385 -0
  130. package/skills/effect-patterns-error-handling/SKILL.md +1212 -0
  131. package/skills/effect-patterns-error-handling-resilience/SKILL.md +179 -0
  132. package/skills/effect-patterns-error-management/SKILL.md +1668 -0
  133. package/skills/effect-patterns-getting-started/SKILL.md +237 -0
  134. package/skills/effect-patterns-making-http-requests/SKILL.md +1756 -0
  135. package/skills/effect-patterns-observability/SKILL.md +1586 -0
  136. package/skills/effect-patterns-platform/SKILL.md +1195 -0
  137. package/skills/effect-patterns-platform-getting-started/SKILL.md +179 -0
  138. package/skills/effect-patterns-project-setup--execution/SKILL.md +233 -0
  139. package/skills/effect-patterns-resource-management/SKILL.md +827 -0
  140. package/skills/effect-patterns-scheduling/SKILL.md +451 -0
  141. package/skills/effect-patterns-scheduling-periodic-tasks/SKILL.md +763 -0
  142. package/skills/effect-patterns-streams/SKILL.md +2052 -0
  143. package/skills/effect-patterns-streams-getting-started/SKILL.md +421 -0
  144. package/skills/effect-patterns-streams-sinks/SKILL.md +1181 -0
  145. package/skills/effect-patterns-testing/SKILL.md +1632 -0
  146. package/skills/effect-patterns-tooling-and-debugging/SKILL.md +1125 -0
  147. package/skills/effect-patterns-value-handling/SKILL.md +676 -0
  148. package/tsconfig.json +20 -0
  149. package/vitest.config.ts +3 -0
@@ -0,0 +1,179 @@
1
+ ---
2
+ name: effect-patterns-error-handling-resilience
3
+ description: Effect-TS patterns for Error Handling Resilience. Use when working with error handling resilience in Effect-TS applications.
4
+ ---
5
+ # Effect-TS Patterns: Error Handling Resilience
6
+ This skill provides 1 curated Effect-TS patterns for error handling resilience.
7
+ Use this skill when working on tasks related to:
8
+ - error handling resilience
9
+ - Best practices in Effect-TS applications
10
+ - Real-world patterns and solutions
11
+
12
+ ---
13
+
14
+ ## 🟡 Intermediate Patterns
15
+
16
+ ### Scheduling Pattern 2: Implement Exponential Backoff for Retries
17
+
18
+ **Rule:** Use exponential backoff with jitter for retries to prevent overwhelming failing services and improve success likelihood through smart timing.
19
+
20
+ **Good Example:**
21
+
22
+ This example demonstrates exponential backoff with jitter for retrying a flaky API call.
23
+
24
+ ```typescript
25
+ import { Effect, Schedule } from "effect";
26
+
27
+ interface RetryStats {
28
+ readonly attempt: number;
29
+ readonly delay: number;
30
+ readonly lastError?: Error;
31
+ }
32
+
33
+ // Simulate flaky API that fails first 3 times, succeeds on 4th
34
+ let attemptCount = 0;
35
+
36
+ const flakyApiCall = (): Effect.Effect<{ status: string }> =>
37
+ Effect.gen(function* () {
38
+ attemptCount++;
39
+ yield* Effect.log(`[API] Attempt ${attemptCount}`);
40
+
41
+ if (attemptCount < 4) {
42
+ yield* Effect.fail(new Error("Service temporarily unavailable (503)"));
43
+ }
44
+
45
+ return { status: "ok" };
46
+ });
47
+
48
+ // Calculate exponential backoff with jitter
49
+ interface BackoffConfig {
50
+ readonly baseDelayMs: number;
51
+ readonly maxDelayMs: number;
52
+ readonly maxRetries: number;
53
+ }
54
+
55
+ const exponentialBackoffWithJitter = (config: BackoffConfig) => {
56
+ let attempt = 0;
57
+
58
+ // Calculate delay for this attempt
59
+ const calculateDelay = (): number => {
60
+ const exponential = config.baseDelayMs * Math.pow(2, attempt);
61
+ const withJitter = exponential * (0.5 + Math.random() * 0.5); // ±50% jitter
62
+ const capped = Math.min(withJitter, config.maxDelayMs);
63
+
64
+ yield* Effect.log(
65
+ `[BACKOFF] Attempt ${attempt + 1}: ${Math.round(capped)}ms delay`
66
+ );
67
+
68
+ return Math.round(capped);
69
+ };
70
+
71
+ return Effect.gen(function* () {
72
+ const effect = flakyApiCall();
73
+
74
+ let lastError: Error | undefined;
75
+
76
+ for (attempt = 0; attempt < config.maxRetries; attempt++) {
77
+ const result = yield* effect.pipe(Effect.either);
78
+
79
+ if (result._tag === "Right") {
80
+ yield* Effect.log(`[SUCCESS] Succeeded on attempt ${attempt + 1}`);
81
+ return result.right;
82
+ }
83
+
84
+ lastError = result.left;
85
+
86
+ if (attempt < config.maxRetries - 1) {
87
+ const delay = calculateDelay();
88
+ yield* Effect.sleep(`${delay} millis`);
89
+ }
90
+ }
91
+
92
+ yield* Effect.log(
93
+ `[FAILURE] All ${config.maxRetries} attempts exhausted`
94
+ );
95
+ yield* Effect.fail(lastError);
96
+ });
97
+ };
98
+
99
+ // Run with exponential backoff
100
+ const program = exponentialBackoffWithJitter({
101
+ baseDelayMs: 100,
102
+ maxDelayMs: 5000,
103
+ maxRetries: 5,
104
+ });
105
+
106
+ console.log(
107
+ `\n[START] Retrying flaky API with exponential backoff\n`
108
+ );
109
+
110
+ Effect.runPromise(program).then(
111
+ (result) => console.log(`\n[RESULT] ${JSON.stringify(result)}\n`),
112
+ (error) => console.error(`\n[ERROR] ${error.message}\n`)
113
+ );
114
+ ```
115
+
116
+ Output demonstrates increasing delays with jitter:
117
+ ```
118
+ [START] Retrying flaky API with exponential backoff
119
+
120
+ [API] Attempt 1
121
+ [BACKOFF] Attempt 1: 78ms delay
122
+ [API] Attempt 2
123
+ [BACKOFF] Attempt 2: 192ms delay
124
+ [API] Attempt 3
125
+ [BACKOFF] Attempt 3: 356ms delay
126
+ [API] Attempt 4
127
+ [SUCCESS] Succeeded on attempt 4
128
+
129
+ [RESULT] {"status":"ok"}
130
+ ```
131
+
132
+ ---
133
+
134
+ **Rationale:**
135
+
136
+ When retrying failed operations, use exponential backoff with jitter: delay doubles on each retry (with random jitter), up to a maximum. This prevents:
137
+
138
+ - **Thundering herd**: All clients retrying simultaneously
139
+ - **Cascade failures**: Overwhelming a recovering service
140
+ - **Resource exhaustion**: Too many queued retry attempts
141
+
142
+ Formula: `delay = min(maxDelay, baseDelay * 2^attempt + random_jitter)`
143
+
144
+ ---
145
+
146
+
147
+ Naive retry strategies fail under load:
148
+
149
+ **Immediate retry**:
150
+ - All failures retry at once
151
+ - Fails service under load (recovery takes longer)
152
+ - Leads to cascade failure
153
+
154
+ **Fixed backoff** (e.g., 1 second always):
155
+ - No pressure reduction during recovery
156
+ - Multiple clients cause thundering herd
157
+ - Predictable = synchronized retries
158
+
159
+ **Exponential backoff**:
160
+ - Gives failing service time to recover
161
+ - Each retry waits progressively longer
162
+ - Without jitter, synchronized retries still hammer service
163
+
164
+ **Exponential backoff + jitter**:
165
+ - Spreads retry attempts over time
166
+ - Failures de-correlate across clients
167
+ - Service recovery time properly utilized
168
+ - Success likelihood increases with each retry
169
+
170
+ Real-world example: 100 clients fail simultaneously
171
+ - **Immediate retry**: 100 requests in milliseconds → failure
172
+ - **Fixed backoff**: 100 requests at exactly 1s → failure
173
+ - **Exponential**: 100 requests at 100ms, 200ms, 400ms, 800ms → recovery → success
174
+
175
+ ---
176
+
177
+ ---
178
+
179
+