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

Fixed #1055 #1064

Merged
merged 7 commits into from
Jan 8, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Removed automatic scoping around ++
  • Loading branch information
mpilquist committed Jan 8, 2018
commit aa50586791e6081cd7578a418b26b1ba88de05ac
5 changes: 3 additions & 2 deletions core/jvm/src/test/scala/fs2/ResourceSafetySpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ class ResourceSafetySpec extends Fs2Spec with EventuallySupport {
Stream.bracket(IO(c.decrementAndGet))(_ => f.get,
_ => IO { c.incrementAndGet; throw Err })
val nested = s0.foldRight(innermost)((i, inner) => bracket(c)(Stream.emit(i) ++ inner))
def allErr(e: CompositeFailure): Boolean = e.all.forall { case Err => true; case _ => false }
try { runLog { nested }; throw Err } // this test should always fail, so the `run` should throw
catch {
case Err => ()
case e: CompositeFailure if e.all.forall(_.isInstanceOf[Err.type]) => ()
case Err => ()
case e: CompositeFailure if allErr(e) => ()
}
withClue(f.tag) { 0L shouldBe c.get }
}
Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/fs2/Pipe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object Pipe {
.eval[Read, Option[Segment[I, Unit]]](FreeC.Eval(identity))
.flatMap {
case None => Stream.empty
case Some(segment) => Stream.segment(segment).appendWithoutScope(prompts)
case Some(segment) => Stream.segment(segment).append(prompts)
}

// Steps `s` without overhead of resource tracking
Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/fs2/Pipe2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ object Pipe2 {
def prompts[X](id: ReadSegment[Option[Segment[X, Unit]]]): Stream[Read, X] =
Stream.eval[Read, Option[Segment[X, Unit]]](FreeC.Eval(id)).flatMap {
case None => Stream.empty
case Some(segment) => Stream.segment(segment).appendWithoutScope(prompts(id))
case Some(segment) => Stream.segment(segment).append(prompts(id))
}
def promptsL: Stream[Read, I] = prompts[I](Left(identity))
def promptsR: Stream[Read, I2] = prompts[I2](Right(identity))
Expand Down
18 changes: 6 additions & 12 deletions core/shared/src/main/scala/fs2/Stream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -873,9 +873,12 @@ final class Stream[+F[_], +O] private (private val free: FreeC[Algebra[Nothing,
/**
* Tracks any resources acquired during this stream and releases them when the stream completes.
*
* Scopes are typically inserted automatically, in between stream appends (i.e., in `s1 ++ s2`,
* a scope is inserted around `s1` when appending) This method allows a scope to be explicitly
* demarcated, so that resources can be freed earlier than when using automatically inserted scopes.
* Scopes are sometimes inserted automatically, (e.g., as a result of calling `handleErrorWith`).
* This method allows a scope to be explicitly demarcated, so that resources can be freed earlier
* than when using automatically inserted scopes.
*
* One use case is scoping the left hand side of an append: `(s1.scope ++ s2)`, which ensures
* resources acquired during `s1` are released onces the end of `s1` has been passed.
*/
def scope: Stream[F, O] = Stream.fromFreeC(Algebra.scope(get))

Expand Down Expand Up @@ -1589,12 +1592,6 @@ object Stream {

/** Appends `s2` to the end of this stream. Alias for `s1 ++ s2`. */
def append[O2 >: O](s2: => Stream[F, O2]): Stream[F, O2] =
fromFreeC(self.scope.get[F, O2].flatMap { _ =>
s2.get
})

/** Appends `s2` to the end of this stream without introducing a new scope around this stream. */
def appendWithoutScope[O2 >: O](s2: => Stream[F, O2]): Stream[F, O2] =
fromFreeC(self.get[F, O2].flatMap { _ =>
s2.get
})
Expand Down Expand Up @@ -2603,9 +2600,6 @@ object Stream {
def append[F[_], O2 >: O](s2: => Stream[F, O2]): Stream[F, O2] =
covary[F].append(s2)

def appendWithoutScope[F[_], O2 >: O](s2: => Stream[F, O2]): Stream[F, O2] =
covary[F].appendWithoutScope(s2)

def concurrently[F[_], O2](that: Stream[F, O2])(implicit F: Effect[F],
ec: ExecutionContext): Stream[F, O] =
covary[F].concurrently(that)
Expand Down