Skip to content

Commit

Permalink
add Concurrency Annotation docs (#3381)
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti authored Jul 30, 2024
1 parent 85a374a commit 8ea4f44
Showing 1 changed file with 86 additions and 4 deletions.
90 changes: 86 additions & 4 deletions packages/schema/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4827,9 +4827,9 @@ console.log(decode("3")) // { _id: 'BigDecimal', value: '1', scale: 0 }
## Annotations

One of the fundamental requirements in the design of `@effect/schema` is that it is extensible and customizable. Customizations are achieved through "annotations". Each node contained in the AST of `@effect/schema/AST` contains an `annotations: Record<symbol, unknown>` field that can be used to attach additional information to the schema.
You can manage these annotations using the `annotations` method.
You can manage these annotations using the `annotations` method ot the `Schema.annotations` API.

Let's see some examples:
**Example of Using Annotations**

```ts
import { Schema } from "@effect/schema"
Expand Down Expand Up @@ -4863,9 +4863,91 @@ const Password =
})
```

The example shows some built-in combinators to add meta information, but users can easily add their own meta information by defining a custom annotation.
This example demonstrates the use of built-in annotations to add metadata like error messages, identifiers, and descriptions to enhance the schema's functionality and documentation.

Here's an example of how to add a `deprecated` annotation:
### Built-in Annotations

The following table provides an overview of common built-in annotations and their uses:

| Annotation | Description |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `identifier` | Assigns a unique identifier to the schema, ideal for TypeScript identifiers and code generation purposes. Commonly used in tools like [TreeFormatter](#customizing-the-output) to clarify output. Examples include `"Person"`, `"Product"`. |
| `title` | Sets a short, descriptive title for the schema, similar to a JSON Schema title. Useful for documentation or UI headings. It is also used by [TreeFormatter](#customizing-the-output) to enhance readability of error messages. |
| `description` | Provides a detailed explanation about the schema's purpose, akin to a JSON Schema description. Used by [TreeFormatter](#customizing-the-output) to provide more detailed error messages. |
| `documentation` | Extends detailed documentation for the schema, beneficial for developers or automated documentation generation. |
| `examples` | Lists examples of valid schema values, akin to the examples attribute in JSON Schema, useful for documentation and validation testing. |
| `default` | Defines a default value for the schema, similar to the default attribute in JSON Schema, to ensure schemas are pre-populated where applicable. |
| `message` | Customizes the error message for validation failures, improving clarity in outputs from tools like [TreeFormatter](#customizing-the-output) and [ArrayFormatter](#arrayformatter) during decoding or validation errors. |
| `jsonSchema` | Specifies annotations that affect the generation of [JSON Schema](#generating-json-schemas) documents, customizing how schemas are represented. |
| `arbitrary` | Configures settings for generating [Arbitrary](#generating-arbitraries) test data. |
| `pretty` | Configures settings for generating [Pretty](#generating-pretty-printers) output. |
| `equivalence` | Configures settings for evaluating data [Equivalence](#generating-equivalences). |
| `concurrency` | Controls concurrency behavior, ensuring schemas perform optimally under concurrent operations. Refer to [Concurrency Annotation](#concurrency-annotation) for detailed usage. |
| `batching` | Manages settings for batching operations to enhance performance when operations can be grouped. |
| `parseIssueTitle` | Provides a custom title for parsing issues, enhancing error descriptions in outputs from [TreeFormatter](#customizing-the-output). See [ParseIssueTitle Annotation](#parseissuetitle-annotation) for more information. |
| `parseOptions` | Allows overriding of parsing options at the schema level, offering granular control over parsing behaviors. See [Customizing Parsing Behavior at the Schema Level](#customizing-parsing-behavior-at-the-schema-level) for application details. |

### Concurrency Annotation

For complex schemas like `Struct`, `Array`, or `Union` that contain multiple nested schemas, the `concurrency` annotation provides a way to manage how validations are executed concurrently:

```ts
import { Schema } from "@effect/schema"
import type { Duration } from "effect"
import { Effect } from "effect"

// Simulates an async task
const item = (id: number, duration: Duration.DurationInput) =>
Schema.String.pipe(
Schema.filterEffect(() =>
Effect.gen(function* () {
yield* Effect.sleep(duration)
console.log(`Task ${id} done`)
return true
})
)
)
```

**Sequential Execution**

```ts
const Sequential = Schema.Tuple(
item(1, "30 millis"),
item(2, "10 millis"),
item(3, "20 millis")
)

Effect.runPromise(Schema.decode(Sequential)(["a", "b", "c"]))
/*
Output
Task 1 done
Task 2 done
Task 3 done
*/
```

**Concurrent Execution**

```ts
const Concurrent = Sequential.annotations({
concurrency: "unbounded"
})

Effect.runPromise(Schema.decode(Concurrent)(["a", "b", "c"]))
/*
Output
Task 2 done
Task 3 done
Task 1 done
*/
```

This configuration allows developers to specify whether validations within a schema should be processed sequentially or concurrently, offering flexibility based on the performance needs and the dependencies between validations.

### Custom Annotations

You can also define your own custom annotations for specific needs. Here's how you can create a `deprecated` annotation:

```ts
import { AST, Schema } from "@effect/schema"
Expand Down

0 comments on commit 8ea4f44

Please sign in to comment.