-
Notifications
You must be signed in to change notification settings - Fork 532
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #595 from rossabaker/1.4.0-backports
1.4.0: omnibus bug fix, feature, and scaladoc backport
- Loading branch information
Showing
17 changed files
with
502 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,4 @@ benchmarks/results | |
.java-version | ||
.DS_Store | ||
.metals | ||
.bloop |
28 changes: 28 additions & 0 deletions
28
core/js/src/main/scala/cats/effect/internals/BlockerPlatform.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (c) 2017-2019 The Typelevel Cats-effect Project Developers | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package cats.effect | ||
package internals | ||
|
||
import scala.concurrent.ExecutionContext | ||
|
||
private[effect] trait BlockerPlatform { | ||
|
||
/** Blocker that delegates to the global execution context. */ | ||
lazy val global: Blocker = liftExecutionContext(ExecutionContext.Implicits.global) | ||
|
||
def liftExecutionContext(ec: ExecutionContext): Blocker | ||
} |
79 changes: 79 additions & 0 deletions
79
core/jvm/src/main/scala/cats/effect/internals/BlockerPlatform.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* Copyright (c) 2017-2019 The Typelevel Cats-effect Project Developers | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package cats.effect | ||
package internals | ||
|
||
import scala.concurrent.ExecutionContext | ||
import java.util.concurrent.{ExecutorService, Executors, ThreadFactory} | ||
import cats.data.NonEmptyList | ||
|
||
private[effect] trait BlockerPlatform { | ||
|
||
/** | ||
* Creates a blocker that is backed by a cached thread pool. | ||
*/ | ||
def apply[F[_]](implicit F: Sync[F]): Resource[F, Blocker] = | ||
fromExecutorService(F.delay(Executors.newCachedThreadPool(new ThreadFactory { | ||
def newThread(r: Runnable) = { | ||
val t = new Thread(r, "cats-effect-blocker") | ||
t.setDaemon(true) | ||
t | ||
} | ||
}))) | ||
|
||
/** | ||
* Creates a blocker backed by the `ExecutorService` returned by the | ||
* supplied task. The executor service is shut down upon finalization | ||
* of the returned resource. | ||
* | ||
* If there are pending tasks in the thread pool at time the returned | ||
* `Blocker` is finalized, the finalizer fails with a `Blocker.OutstandingTasksAtShutdown` | ||
* exception. | ||
*/ | ||
def fromExecutorService[F[_]](makeExecutorService: F[ExecutorService])(implicit F: Sync[F]): Resource[F, Blocker] = | ||
Resource.make(makeExecutorService) { ec => | ||
val tasks = F.delay { | ||
val tasks = ec.shutdownNow() | ||
val b = List.newBuilder[Runnable] | ||
val itr = tasks.iterator | ||
while (itr.hasNext) | ||
b += itr.next | ||
NonEmptyList.fromList(b.result) | ||
} | ||
F.flatMap(tasks) { | ||
case Some(t) => F.raiseError(new OutstandingTasksAtShutdown(t)) | ||
case None => F.unit | ||
} | ||
}.map(es => liftExecutorService(es)) | ||
|
||
/** | ||
* Creates a blocker that delegates to the supplied executor service. | ||
*/ | ||
def liftExecutorService(es: ExecutorService): Blocker = | ||
liftExecutionContext(ExecutionContext.fromExecutorService(es)) | ||
|
||
/** | ||
* Creates a blocker that delegates to the supplied execution context. | ||
* | ||
* This must not be used with general purpose contexts like | ||
* `scala.concurrent.ExecutionContext.Implicits.global'. | ||
*/ | ||
def liftExecutionContext(ec: ExecutionContext): Blocker | ||
|
||
/** Thrown if there are tasks queued in the thread pool at the time a `Blocker` is finalized. */ | ||
final class OutstandingTasksAtShutdown(val tasks: NonEmptyList[Runnable]) extends IllegalStateException("There were outstanding tasks at time of shutdown of the thread pool") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (c) 2017-2019 The Typelevel Cats-effect Project Developers | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package cats | ||
package effect | ||
|
||
import scala.concurrent.ExecutionContext | ||
|
||
import cats.effect.internals.BlockerPlatform | ||
|
||
/** | ||
* An execution context that is safe to use for blocking operations. | ||
* | ||
* Used in conjunction with [[ContextShift]], this type allows us to write functions | ||
* that require a special `ExecutionContext` for evaluation, while discouraging the | ||
* use of a shared, general purpose pool (e.g. the global context). | ||
* | ||
* Instances of this class should *not* be passed implicitly. | ||
*/ | ||
final class Blocker private (val blockingContext: ExecutionContext) extends AnyVal { | ||
|
||
/** | ||
* Like `Sync#delay` but the supplied thunk is evaluated on the blocking | ||
* execution context. | ||
*/ | ||
def delay[F[_], A](thunk: => A)(implicit F: Sync[F], cs: ContextShift[F]): F[A] = | ||
blockOn(F.delay(thunk)) | ||
|
||
/** | ||
* Evaluates the supplied task on the blocking execution context via `blockOn`. | ||
*/ | ||
def blockOn[F[_], A](fa: F[A])(implicit cs: ContextShift[F]): F[A] = | ||
cs.evalOn(this.blockingContext)(fa) | ||
} | ||
|
||
object Blocker extends BlockerPlatform { | ||
|
||
/** | ||
* Creates a blocker that delegates to the supplied execution context. | ||
* | ||
* This must not be used with general purpose contexts like | ||
* `scala.concurrent.ExecutionContext.Implicits.global'. | ||
*/ | ||
def liftExecutionContext(ec: ExecutionContext): Blocker = new Blocker(ec) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.