Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update effect #434

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"devDependencies": {
"@effect/language-service": "^0.0.21",
"@effect/opentelemetry": "^0.27.0",
"@effect/opentelemetry": "^0.30.7",
"@mdx-js/mdx": "^2.3.0",
"@opentelemetry/exporter-trace-otlp-http": "0.43.0",
"@opentelemetry/sdk-trace-base": "^1.17.1",
Expand All @@ -34,7 +34,7 @@
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"autoprefixer": "^10.4.14",
"effect": "2.0.0-next.60",
"effect": "2.1.1",
"eslint": "^8.38.0",
"eslint-config-next": "^13.3.0",
"eslint-config-prettier": "^8.8.0",
Expand Down
4 changes: 2 additions & 2 deletions pages/docs/error-management/retrying.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ Effect.retry(effect, policy)

```

## retryN
## retry n times

There is a shortcut when the policy is trivial and the failed effect is immediately retried: `retryN(effect)`.
There is a shortcut when the policy is trivial and the failed effect is immediately retried:

```ts file=<rootDir>/src/guide/error-management/retrying/retryN.ts

Expand Down
12 changes: 6 additions & 6 deletions pages/docs/error-management/timing-out.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ In the world of programming, we often deal with tasks that take some time to com

## timeout

Effect lets us timeout any effect using the `Effect.timeout` function, which returns a new effect that succeeds with an [`Option`](../data-types/option):
Effect lets us timeout any effect using the `Effect.timeout` function. It returns a new effect with the following characteristics:

- A `None` indicates that the timeout elapsed before the effect could complete its execution.
- A `Some` indicates that the effect completed before the timeout elapsed, and the `Some` contains the result of the effect.
- If an error is returned, it signifies that the timeout expired before the completion of the effect's execution.
- If successful, it indicates that the effect finished within the specified timeout, and the result of the effect is included.

If an effect times out, then instead of continuing to execute in the background, it will be interrupted so no resources will be wasted.

Expand All @@ -19,19 +19,19 @@ Suppose we have the following effect:

When we apply `Effect.timeout` to `program`, it behaves in one of the following ways:

1. If the original effect (`program` in this case) completes before the timeout elapses, it returns `Some` of the produced value by the original effect. Here's an example:
1. If the original effect (`program` in this case) completes before the timeout elapses, it returns the produced value by the original effect. Here's an example:

```ts file=<rootDir>/src/guide/error-management/timing-out/1.ts

```

2. If the timeout elapses before the original effect completes, and the effect is interruptible, it will be immediately interrupted, and the timeout operation produces a `None` value. Here's an example:
2. If the timeout elapses before the original effect completes, and the effect is interruptible, it will be immediately interrupted, and the timeout operation produces a `NoSuchElementException` error. Here's an example:

```ts file=<rootDir>/src/guide/error-management/timing-out/2.ts

```

3. If the effect is uninterruptible, it will be blocked until the original effect safely finishes its work, and then the timeout operator produces a `None` value. Here's an example:
3. If the effect is uninterruptible, it will be blocked until the original effect safely finishes its work, and then the timeout operator produces a `NoSuchElementException` error. Here's an example:

```ts file=<rootDir>/src/guide/error-management/timing-out/3.ts

Expand Down
20 changes: 10 additions & 10 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/guide/error-management/retrying/retryN.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Effect } from "effect"
import { effect } from "./fake"

Effect.runPromise(Effect.retryN(effect, 5))
Effect.runPromise(Effect.retry(effect, { times: 5 }))
/*
Output:
failure
Expand Down
10 changes: 3 additions & 7 deletions src/guide/error-management/timing-out/1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,13 @@ const program = Effect.gen(function* (_) {
return "some result"
})

// $ExpectType Effect<never, never, Option<string>>
// $ExpectType Effect<never, NoSuchElementException, string>
const main = program.pipe(Effect.timeout("3 seconds"))

Effect.runPromise(main).then(console.log)
Effect.runPromise(main).then(console.log, console.error)
/*
Output:
start doing something...
my job is finished!
{
_id: "Option",
_tag: "Some",
value: "some result"
}
some result
*/
12 changes: 8 additions & 4 deletions src/guide/error-management/timing-out/2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ const program = Effect.gen(function* (_) {
return "some result"
})

// $ExpectType Effect<never, never, Option<string>>
// $ExpectType Effect<never, NoSuchElementException, string>
const main = program.pipe(Effect.timeout("1 seconds"))

Effect.runPromise(main).then(console.log)
Effect.runPromise(main).then(console.log, console.error)
/*
Output:
start doing something...
{
_id: "Option",
_tag: "None"
_id: 'FiberFailure',
cause: {
_id: 'Cause',
_tag: 'Fail',
failure: { _tag: 'NoSuchElementException' }
}
}
*/
12 changes: 8 additions & 4 deletions src/guide/error-management/timing-out/3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ const program = Effect.gen(function* (_) {
return "some result"
})

// $ExpectType Effect<never, never, Option<string>>
// $ExpectType Effect<never, NoSuchElementException, string>
const main = program.pipe(Effect.uninterruptible, Effect.timeout("1 seconds"))

Effect.runPromise(main).then(console.log)
Effect.runPromise(main).then(console.log, console.error)
/*
Output:
start doing something...
my job is finished!
{
_id: "Option",
_tag: "None"
_id: 'FiberFailure',
cause: {
_id: 'Cause',
_tag: 'Fail',
failure: { _tag: 'NoSuchElementException' }
}
}
*/
12 changes: 8 additions & 4 deletions src/guide/error-management/timing-out/disconnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@ const program = Effect.gen(function* (_) {
return "some result"
})

// $ExpectType Effect<never, never, Option<string>>
// $ExpectType Effect<never, NoSuchElementException, string>
const main = program.pipe(
Effect.uninterruptible,
Effect.disconnect,
Effect.timeout("1 seconds")
)

Effect.runPromise(main).then(console.log)
Effect.runPromise(main).then(console.log, console.error)
/*
Output:
start doing something...
{
_id: "Option",
_tag: "None"
_id: 'FiberFailure',
cause: {
_id: 'Cause',
_tag: 'Fail',
failure: { _tag: 'NoSuchElementException' }
}
}
my job is finished!
*/
2 changes: 1 addition & 1 deletion src/guide/error-management/timing-out/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ const program = Effect.gen(function* (_) {
return "some result"
})

// $ExpectType Effect<never, never, Option<string>>
// $ExpectType Effect<never, NoSuchElementException, string>
const main = program.pipe(Effect.timeout("3 seconds"))
12 changes: 10 additions & 2 deletions src/guide/error-management/timing-out/timeoutFail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,17 @@ const main = program.pipe(
})
)

Effect.runPromise(main).then(console.log)
Effect.runPromise(main).then(console.log, console.error)
/*
Output:
start doing something...
Error: timeout
{
_id: 'FiberFailure',
cause: {
_id: 'Cause',
_tag: 'Fail',
failure: Error: timeout
... stack trace ...
}
}
*/
2 changes: 1 addition & 1 deletion src/guide/error-management/timing-out/timeoutTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const program = Effect.gen(function* (_) {
const main = program.pipe(
Effect.timeoutTo({
duration: "1 seconds",
// let's return an Either instead of an Option
// let's return an Either
onSuccess: (result): Either.Either<string, string> => Either.right(result),
onTimeout: (): Either.Either<string, string> => Either.left("timeout!")
})
Expand Down
4 changes: 2 additions & 2 deletions src/guide/state-management/ref/example-2-concurrent-pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const getNames = Ref.make(Chunk.empty<string>()).pipe(
const fiber1 = ReadLine.readLine(
"Please enter a name or `q` to exit: "
).pipe(
Effect.repeatWhileEffect((name) => {
Effect.repeat({ while: (name) => {
if (name === "q") {
return Effect.succeed(false)
} else {
Expand All @@ -16,7 +16,7 @@ const getNames = Ref.make(Chunk.empty<string>()).pipe(
Effect.as(true)
)
}
}),
} }),
Effect.fork
)
const fiber2 = Effect.fork(
Expand Down
4 changes: 2 additions & 2 deletions src/guide/state-management/ref/example-2-pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as ReadLine from "./ReadLine"
const getNames = Ref.make(Chunk.empty<string>()).pipe(
Effect.flatMap((ref) =>
ReadLine.readLine("Please enter a name or `q` to exit: ").pipe(
Effect.repeatWhileEffect((name) => {
Effect.repeat({ while: (name) => {
if (name === "q") {
return Effect.succeed(false)
} else {
Expand All @@ -14,7 +14,7 @@ const getNames = Ref.make(Chunk.empty<string>()).pipe(
Effect.as(true)
)
}
}),
} }),
Effect.flatMap(() => Ref.get(ref))
)
)
Expand Down
6 changes: 5 additions & 1 deletion src/testing/clock/timeout-pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import * as assert from "node:assert"

const test = pipe(
Effect.sleep("5 minutes"),
Effect.timeout("1 minutes"),
Effect.timeoutTo({
duration: "1 minutes",
onSuccess: Option.some,
onTimeout: () => Option.none<void>()
}),
Effect.fork,
Effect.tap(() =>
// Adjust the TestClock by 1 minute to simulate the passage of time
Expand Down
6 changes: 5 additions & 1 deletion src/testing/clock/timeout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ const test = Effect.gen(function* (_) {
// Create a fiber that sleeps for 5 minutes and then times out after 1 minute
const fiber = yield* _(
Effect.sleep("5 minutes"),
Effect.timeout("1 minutes"),
Effect.timeoutTo({
duration: "1 minutes",
onSuccess: Option.some,
onTimeout: () => Option.none<void>()
}),
Effect.fork
)

Expand Down
Loading