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

Consistency between batching and fiber state #1706

Merged
merged 1 commit into from
Nov 29, 2023
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
9 changes: 9 additions & 0 deletions .changeset/honest-readers-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"effect": patch
---

Improve consistency between request batching and fiber environment.

In prior releases request batching required operators that act on fiber context such as `Effect.locally` to be aware of batching in order to avoid bugs where the effect executed post batching would lose the fiber environment (context, refs, and flags).

This change restructure how batching internally works, inside the fiber we now slice up the stack and restore the exact context that was destroyed, by rewriting the internals of forEach batching is now transparent to any other function that deals with fiber state.
29 changes: 6 additions & 23 deletions docs/modules/Effect.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ Added in v2.0.0
- [requests & batching](#requests--batching)
- [blocked](#blocked)
- [cacheRequestResult](#cacherequestresult)
- [flatMapStep](#flatmapstep)
- [request](#request)
- [runRequestBlock](#runrequestblock)
- [step](#step)
Expand Down Expand Up @@ -4121,10 +4120,10 @@ Added in v2.0.0
**Signature**

```ts
export interface Blocked<out R, out E, out A> extends Effect<R, E, A> {
export interface Blocked<out E, out A> extends Effect<never, E, A> {
readonly _op: "Blocked"
readonly i0: RequestBlock<R>
readonly i1: Effect<R, E, A>
readonly i0: RequestBlock
readonly i1: Effect<never, E, A>
}
```

Expand Down Expand Up @@ -4615,10 +4614,7 @@ Added in v2.0.0
**Signature**

```ts
export declare const blocked: <R, E, A>(
blockedRequests: RequestBlock<R>,
_continue: Effect<R, E, A>
) => Blocked<R, E, A>
export declare const blocked: <E, A>(blockedRequests: RequestBlock, _continue: Effect<never, E, A>) => Blocked<E, A>
```

Added in v2.0.0
Expand All @@ -4636,19 +4632,6 @@ export declare const cacheRequestResult: <A extends Request.Request<any, any>>(

Added in v2.0.0

## flatMapStep

**Signature**

```ts
export declare const flatMapStep: <R, E, A, R1, E1, B>(
self: Effect<R, E, A>,
f: (step: Exit.Exit<E, A> | Blocked<R, E, A>) => Effect<R1, E1, B>
) => Effect<R | R1, E1, B>
```

Added in v2.0.0

## request

**Signature**
Expand All @@ -4674,7 +4657,7 @@ Added in v2.0.0
**Signature**

```ts
export declare const runRequestBlock: <R>(blockedRequests: RequestBlock<R>) => Blocked<R, never, void>
export declare const runRequestBlock: <R>(blockedRequests: RequestBlock) => Effect<R, never, void>
```

Added in v2.0.0
Expand All @@ -4684,7 +4667,7 @@ Added in v2.0.0
**Signature**

```ts
export declare const step: <R, E, A>(self: Effect<R, E, A>) => Effect<R, E, Exit.Exit<E, A> | Blocked<R, E, A>>
export declare const step: <R, E, A>(self: Effect<R, E, A>) => Effect<R, E, Exit.Exit<E, A> | Blocked<E, A>>
```

Added in v2.0.0
Expand Down
76 changes: 22 additions & 54 deletions docs/modules/RequestBlock.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ Added in v2.0.0
- [Reducer (interface)](#reducer-interface)
- [Seq (interface)](#seq-interface)
- [Single (interface)](#single-interface)
- [utils](#utils)
- [locally](#locally)
- [mapInputContext](#mapinputcontext)

---

Expand All @@ -40,7 +37,7 @@ Added in v2.0.0
**Signature**

```ts
export declare const empty: RequestBlock<never>
export declare const empty: RequestBlock
```

Added in v2.0.0
Expand All @@ -50,10 +47,10 @@ Added in v2.0.0
**Signature**

```ts
export declare const mapRequestResolvers: <R, A, R2>(
self: RequestBlock<R>,
f: (dataSource: RequestResolver.RequestResolver<A, R>) => RequestResolver.RequestResolver<A, R2>
) => RequestBlock<R | R2>
export declare const mapRequestResolvers: <A>(
self: RequestBlock,
f: (dataSource: RequestResolver.RequestResolver<A, never>) => RequestResolver.RequestResolver<A, never>
) => RequestBlock
```

Added in v2.0.0
Expand All @@ -63,7 +60,7 @@ Added in v2.0.0
**Signature**

```ts
export declare const parallel: <R, R2>(self: RequestBlock<R>, that: RequestBlock<R2>) => RequestBlock<R | R2>
export declare const parallel: (self: RequestBlock, that: RequestBlock) => RequestBlock
```

Added in v2.0.0
Expand All @@ -73,7 +70,7 @@ Added in v2.0.0
**Signature**

```ts
export declare const reduce: <R, Z>(self: RequestBlock<R>, reducer: RequestBlock.Reducer<R, Z>) => Z
export declare const reduce: <Z>(self: RequestBlock, reducer: RequestBlock.Reducer<Z>) => Z
```

Added in v2.0.0
Expand All @@ -83,7 +80,7 @@ Added in v2.0.0
**Signature**

```ts
export declare const sequential: <R, R2>(self: RequestBlock<R>, that: RequestBlock<R2>) => RequestBlock<R | R2>
export declare const sequential: (self: RequestBlock, that: RequestBlock) => RequestBlock
```

Added in v2.0.0
Expand All @@ -93,10 +90,10 @@ Added in v2.0.0
**Signature**

```ts
export declare const single: <R, A>(
dataSource: RequestResolver.RequestResolver<A, R>,
export declare const single: <A>(
dataSource: RequestResolver.RequestResolver<A, never>,
blockedRequest: Request.Entry<A>
) => RequestBlock<R>
) => RequestBlock
```

Added in v2.0.0
Expand All @@ -120,10 +117,10 @@ Added in v2.0.0
**Signature**

```ts
export interface Par<out R> {
export interface Par {
readonly _tag: "Par"
readonly left: RequestBlock<R>
readonly right: RequestBlock<R>
readonly left: RequestBlock
readonly right: RequestBlock
}
```

Expand All @@ -140,7 +137,7 @@ preserving ordering guarantees.
**Signature**

```ts
export type RequestBlock<R> = Empty | Par<R> | Seq<R> | Single<R>
export type RequestBlock = Empty | Par | Seq | Single
```

Added in v2.0.0
Expand All @@ -154,10 +151,10 @@ Added in v2.0.0
**Signature**

```ts
export interface Reducer<in R, in out Z> {
export interface Reducer<in out Z> {
emptyCase(): Z
parCase(left: Z, right: Z): Z
singleCase(dataSource: RequestResolver.RequestResolver<unknown, R>, blockedRequest: Request.Entry<unknown>): Z
singleCase(dataSource: RequestResolver.RequestResolver<unknown, never>, blockedRequest: Request.Entry<unknown>): Z
seqCase(left: Z, right: Z): Z
}
```
Expand All @@ -169,10 +166,10 @@ Added in v2.0.0
**Signature**

```ts
export interface Seq<out R> {
export interface Seq {
readonly _tag: "Seq"
readonly left: RequestBlock<R>
readonly right: RequestBlock<R>
readonly left: RequestBlock
readonly right: RequestBlock
}
```

Expand All @@ -183,40 +180,11 @@ Added in v2.0.0
**Signature**

```ts
export interface Single<out R> {
export interface Single {
readonly _tag: "Single"
readonly dataSource: RequestResolver.RequestResolver<unknown, R>
readonly dataSource: RequestResolver.RequestResolver<unknown, never>
readonly blockedRequest: Request.Entry<unknown>
}
```

Added in v2.0.0

# utils

## locally

Provides each data source with a fiber ref value.

**Signature**

```ts
export declare const locally: <R, A>(self: RequestBlock<R>, ref: FiberRef<A>, value: A) => RequestBlock<R>
```

Added in v2.0.0

## mapInputContext

Provides each data source with part of its required environment.

**Signature**

```ts
export declare const mapInputContext: <R0, R>(
self: RequestBlock<R>,
f: (context: Context.Context<R0>) => Context.Context<R>
) => RequestBlock<R0>
```

Added in v2.0.0
21 changes: 6 additions & 15 deletions src/Effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@ export interface EffectTypeLambda extends TypeLambda {
* @since 2.0.0
* @category models
*/
export interface Blocked<out R, out E, out A> extends Effect<R, E, A> {
export interface Blocked<out E, out A> extends Effect<never, E, A> {
readonly _op: "Blocked"
readonly i0: RequestBlock<R>
readonly i1: Effect<R, E, A>
readonly i0: RequestBlock
readonly i1: Effect<never, E, A>
}

/**
Expand Down Expand Up @@ -4880,29 +4880,20 @@ export const ap: {
* @category requests & batching
* @since 2.0.0
*/
export const blocked: <R, E, A>(blockedRequests: RequestBlock<R>, _continue: Effect<R, E, A>) => Blocked<R, E, A> =
export const blocked: <E, A>(blockedRequests: RequestBlock, _continue: Effect<never, E, A>) => Blocked<E, A> =
core.blocked

/**
* @category requests & batching
* @since 2.0.0
*/
export const runRequestBlock: <R>(blockedRequests: RequestBlock<R>) => Blocked<R, never, void> = core.runRequestBlock
export const runRequestBlock: <R>(blockedRequests: RequestBlock) => Effect<R, never, void> = core.runRequestBlock

/**
* @category requests & batching
* @since 2.0.0
*/
export const step: <R, E, A>(self: Effect<R, E, A>) => Effect<R, E, Exit.Exit<E, A> | Blocked<R, E, A>> = core.step

/**
* @category requests & batching
* @since 2.0.0
*/
export const flatMapStep: <R, E, A, R1, E1, B>(
self: Effect<R, E, A>,
f: (step: Exit.Exit<E, A> | Blocked<R, E, A>) => Effect<R1, E1, B>
) => Effect<R | R1, E1, B> = core.flatMapStep
export const step: <R, E, A>(self: Effect<R, E, A>) => Effect<R, E, Exit.Exit<E, A> | Blocked<E, A>> = core.step

/**
* @since 2.0.0
Expand Down
Loading