linebacker


License

License

MIT
GroupId

GroupId

io.chrisdavenport
ArtifactId

ArtifactId

linebacker_2.12
Last Version

Last Version

0.2.1
Release Date

Release Date

Type

Type

jar
Description

Description

linebacker
linebacker
Project URL

Project URL

https://github.com/ChristopherDavenport/linebacker
Project Organization

Project Organization

io.chrisdavenport
Source Code Management

Source Code Management

https://github.com/ChristopherDavenport/linebacker

Download linebacker_2.12

How to add to project

<!-- https://jarcasting.com/artifacts/io.chrisdavenport/linebacker_2.12/ -->
<dependency>
    <groupId>io.chrisdavenport</groupId>
    <artifactId>linebacker_2.12</artifactId>
    <version>0.2.1</version>
</dependency>
// https://jarcasting.com/artifacts/io.chrisdavenport/linebacker_2.12/
implementation 'io.chrisdavenport:linebacker_2.12:0.2.1'
// https://jarcasting.com/artifacts/io.chrisdavenport/linebacker_2.12/
implementation ("io.chrisdavenport:linebacker_2.12:0.2.1")
'io.chrisdavenport:linebacker_2.12:jar:0.2.1'
<dependency org="io.chrisdavenport" name="linebacker_2.12" rev="0.2.1">
  <artifact name="linebacker_2.12" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.chrisdavenport', module='linebacker_2.12', version='0.2.1')
)
libraryDependencies += "io.chrisdavenport" % "linebacker_2.12" % "0.2.1"
[io.chrisdavenport/linebacker_2.12 "0.2.1"]

Dependencies

compile (2)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.12.8
org.typelevel : cats-effect_2.12 jar 1.3.1

test (1)

Group / Artifact Type Version
org.specs2 : specs2-core_2.12 jar 4.5.1

Project Modules

There are no modules declared in this project.

Linebacker Build Status Maven Central Gitter chat

Enabling Functional Blocking where you need it.

Quick Start

To use linebacker in an existing SBT project with Scala 2.11 or a later version, add the following dependency to your build.sbt:

libraryDependencies += "io.chrisdavenport" %% "linebacker" % "<version>"

Why Linebacker

Concurrency is hard.

No Seriously, Why Linebacker

Generally threading models have to deal with the idea that in java/scala some of our fundamental calls are still blocking. Looking at you JDBC! In order to handle this we generally utilize Executors or ExecutionContexts. Additionally many libraries now utilize implicit execution contexts for their shifting. This puts us in a position where we need to manually and explicitly pass around two contexts raising one explicitly where appropriate and then shifting work back and forth from the pools as appropriate.

Here is where we attempt to make these patterns easier. This library provides abstractions for managing pools and shifting behavior between your pools.

Why should you care? Let us propose you have a single pool on 5 threads and you receive 5 requests that require communicating with a database. What happens if a 6th call comes in when all these CPU bound threads are blocked on network IO? Obviously we are waiting for threads.

Some additional resources for why this is important:

Thread pool best practices.
For more info, see @djspiewak & @alexelcu posts:https://t.co/pr6McpU3tHhttps://t.co/Vz617IMjRB pic.twitter.com/gJgzZI6yGJ

— Impure Pics (@impurepics) April 21, 2018
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Examples

First some imports

import scala.concurrent.ExecutionContext.global
import cats.effect._
import cats.implicits._
import io.chrisdavenport.linebacker.Linebacker
import io.chrisdavenport.linebacker.contexts.Executors

Creating And Evaluating Pool Behavior

val getThread = IO(Thread.currentThread().getName)

val checkRun = {
  Executors.unbound[IO] // Create Executor
    .map(Linebacker.fromExecutorService[IO](_)) // Create Linebacker From Executor
    .use{ implicit linebacker => // Raise Implicitly
      implicit val cs = IO.contextShift(global)
      Linebacker[IO].blockCS(getThread) // Block On Linebacker Pool Not Global
        .flatMap(threadName => IO(println(threadName))) >>
      getThread // Running On Global
        .flatMap(threadName => IO(println(threadName)))
    }
}

checkRun.unsafeRunSync

Dual Contexts Are Also Very Useful

import scala.concurrent.ExecutionContext
import io.chrisdavenport.linebacker.DualContext

Executors.unbound[IO].map(blockingExecutor =>
  DualContext.fromContexts[IO](IO.contextShift(global),  ExecutionContext.fromExecutorService(blockingExecutor))
)

Versions

Version
0.2.1
0.2.0
0.2.0-M2
0.2.0-M1
0.1.0
0.0.4
0.0.3
0.0.2
0.0.1