scala.concurrent.ExecutionContextExecutorService Scala Examples

The following examples show how to use scala.concurrent.ExecutionContextExecutorService. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: ExecutorPlatformSpecific.scala    From zio   with Apache License 2.0 5 votes vote down vote up
package zio.internal

import java.util.concurrent.{ AbstractExecutorService, TimeUnit }
import java.{ util => ju }

import scala.concurrent.{ ExecutionContext, ExecutionContextExecutorService }

trait ExecutorPlatformSpecific { this: Executor =>

  
  lazy val asECES: ExecutionContextExecutorService =
    new AbstractExecutorService with ExecutionContextExecutorService {
      override val prepare: ExecutionContext                               = asEC
      override val isShutdown: Boolean                                     = false
      override val isTerminated: Boolean                                   = false
      override val shutdown: Unit                                          = ()
      override val shutdownNow: ju.List[Runnable]                          = ju.Collections.emptyList[Runnable]
      override def execute(runnable: Runnable): Unit                       = asEC execute runnable
      override def reportFailure(t: Throwable): Unit                       = asEC reportFailure t
      override def awaitTermination(length: Long, unit: TimeUnit): Boolean = false
    }

} 
Example 2
Source File: ExecutorPlatformSpecific.scala    From zio   with Apache License 2.0 5 votes vote down vote up
package zio.internal

import java.util.concurrent.{ AbstractExecutorService, TimeUnit }
import java.{ util => ju }

import scala.concurrent.{ ExecutionContext, ExecutionContextExecutorService }

trait ExecutorPlatformSpecific { this: Executor =>

  
  lazy val asECES: ExecutionContextExecutorService =
    new AbstractExecutorService with ExecutionContextExecutorService {
      override val prepare: ExecutionContext                               = asEC
      override val isShutdown: Boolean                                     = false
      override val isTerminated: Boolean                                   = false
      override val shutdown: Unit                                          = ()
      override val shutdownNow: ju.List[Runnable]                          = ju.Collections.emptyList[Runnable]
      override def execute(runnable: Runnable): Unit                       = asEC execute runnable
      override def reportFailure(t: Throwable): Unit                       = asEC reportFailure t
      override def awaitTermination(length: Long, unit: TimeUnit): Boolean = false
    }

} 
Example 3
Source File: RerunnableContextShift.scala    From catbird   with Apache License 2.0 5 votes vote down vote up
package io.catbird.util.effect

import cats.effect.ContextShift
import com.twitter.util.{ Future, FuturePool, Promise }
import io.catbird.util.Rerunnable

import scala.Unit
import java.lang.Runnable
import java.util.concurrent.ExecutorService

import scala.concurrent.{ ExecutionContext, ExecutionContextExecutorService }


  object Implicits {
    final implicit def global: ContextShift[Rerunnable] = RerunnableContextShift.global
  }
}

final private[effect] class RerunnableContextShift private (ec: ExecutionContext) extends ContextShift[Rerunnable] {
  private final lazy val futurePool = FuturePool.interruptible(ec.asInstanceOf[ExecutionContextExecutorService])

  override def shift: Rerunnable[Unit] =
    Rerunnable.withFuturePool(futurePool)(()) // This is a bit of a hack, but it will have to do

  override def evalOn[A](targetEc: ExecutionContext)(fa: Rerunnable[A]): Rerunnable[A] =
    for {
      r <- executeOn(targetEc)(fa).liftToTry
      _ <- shift
      a <- Rerunnable.fromFuture(Future.value(r).lowerFromTry)
    } yield a

  private def executeOn[A](targetEc: ExecutionContext)(fa: Rerunnable[A]): Rerunnable[A] =
    Rerunnable.fromFuture {
      val p = Promise[A]()

      targetEc.execute(new Runnable {
        override def run(): Unit =
          fa.run.proxyTo[A](p)
      })

      p
    }
} 
Example 4
Source File: ThreadPoolNamingSupport.scala    From catbird   with Apache License 2.0 5 votes vote down vote up
package io.catbird.util.effect

import java.lang.{ Runnable, Thread }
import java.util.concurrent.{ Executors, ThreadFactory }

import scala.concurrent.{ ExecutionContext, ExecutionContextExecutorService }

trait ThreadPoolNamingSupport {

  def newNamedThreadPool(name: String): ExecutionContextExecutorService =
    ExecutionContext.fromExecutorService(
      Executors.newSingleThreadExecutor(new ThreadFactory {
        override def newThread(r: Runnable): Thread = {
          val thread = Executors.defaultThreadFactory().newThread(r)
          thread.setName(name)
          thread.setDaemon(true) // Don't block shutdown of JVM
          thread
        }
      })
    )

  def currentThreadName(): String = Thread.currentThread().getName
} 
Example 5
Source File: Executors.scala    From kafka-journal   with MIT License 5 votes vote down vote up
package com.evolutiongaming.kafka.journal.util

import java.util.concurrent.ScheduledExecutorService

import cats.effect.{Resource, Sync}
import com.evolutiongaming.catshelper.Runtime
import com.evolutiongaming.kafka.journal.execution.{ForkJoinPoolOf, ScheduledExecutorServiceOf, ThreadFactoryOf, ThreadPoolOf}

import scala.concurrent.{ExecutionContext, ExecutionContextExecutorService}

object Executors {

  def blocking[F[_] : Sync](
    name: String,
  ): Resource[F, ExecutionContextExecutorService] = {
    for {
      threadFactory <- Resource.liftF(ThreadFactoryOf[F](name))
      threadPool    <- ThreadPoolOf[F](2, Int.MaxValue, threadFactory)
    } yield {
      ExecutionContext.fromExecutorService(threadPool)
    }
  }


  def nonBlocking[F[_] : Sync](
    name: String,
  ): Resource[F, ExecutionContextExecutorService] = {
    for {
      cores        <- Resource.liftF(Runtime[F].availableCores)
      parallelism   = cores + 1
      forkJoinPool <- ForkJoinPoolOf[F](name, parallelism)
    } yield {
      ExecutionContext.fromExecutorService(forkJoinPool)
    }
  }


  def scheduled[F[_] : Sync](
    name: String,
    parallelism: Int
  ): Resource[F, ScheduledExecutorService] = {
    for {
      threadFactory <- Resource.liftF(ThreadFactoryOf[F](name))
      result        <- ScheduledExecutorServiceOf[F](parallelism, threadFactory)
    } yield result
  }
} 
Example 6
Source File: ExecutorServiceWrapper.scala    From monix-nio   with Apache License 2.0 5 votes vote down vote up
package monix.nio.internal

import java.util
import java.util.concurrent.{ AbstractExecutorService, ExecutorService, TimeUnit }

import monix.execution.schedulers.{ ReferenceScheduler, SchedulerService }
import monix.execution.{ Cancelable, ExecutionModel, Scheduler }

import scala.collection.JavaConverters._
import scala.concurrent.duration.Duration
import scala.concurrent.{ Await, ExecutionContextExecutorService }


  private val currentThread: Scheduler =
    new ReferenceScheduler {
      import monix.execution.Scheduler.global
      def execute(r: Runnable): Unit = r.run()
      def reportFailure(t: Throwable): Unit = throw t
      def scheduleOnce(initialDelay: Long, unit: TimeUnit, r: Runnable): Cancelable =
        global.scheduleOnce(initialDelay, unit, r)
      def executionModel: ExecutionModel =
        ExecutionModel.Default
    }
} 
Example 7
Source File: PlatformCatsImplicits.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.interop

import java.util.concurrent.ExecutorService

import _root_.cats.instances.vector._
import _root_.cats.syntax.all._
import coursier.util.Sync

import scala.concurrent.{ExecutionContext, ExecutionContextExecutorService}

abstract class PlatformCatsImplicits {

  implicit def coursierSyncFromCats[F[_], F0[_]](implicit N: _root_.cats.effect.Sync[F], par: _root_.cats.Parallel.Aux[F, F0], cs: _root_.cats.effect.ContextShift[F]): Sync[F] =
    new Sync[F] {
      def point[A](a: A): F[A] =
        a.pure[F]
      def delay[A](a: => A): F[A] =
        N.delay(a)
      override def fromAttempt[A](a: Either[Throwable, A]): F[A] =
        N.fromEither(a)
      def handle[A](a: F[A])(f: PartialFunction[Throwable, A]): F[A] =
        a.recover(f)
      def schedule[A](pool: ExecutorService)(f: => A): F[A] = {
        val ec0 = pool match {
          case eces: ExecutionContextExecutorService => eces
          case _ => ExecutionContext.fromExecutorService(pool) // FIXME Is this instantiation costly? Cache it?
        }
        cs.evalOn(ec0)(N.delay(f))
      }

      def gather[A](elems: Seq[F[A]]): F[Seq[A]] =
        N.map(_root_.cats.Parallel.parSequence(elems.toVector))(_.toSeq)
      def bind[A, B](elem: F[A])(f: A => F[B]): F[B] =
        elem.flatMap(f)
    }

} 
Example 8
Source File: PlatformTaskCompanion.scala    From coursier   with Apache License 2.0 5 votes vote down vote up
package coursier.util

import java.util.concurrent.{ExecutorService, ScheduledExecutorService}

import scala.concurrent.{Await, ExecutionContext, ExecutionContextExecutorService, Future}
import scala.concurrent.duration.{Duration, FiniteDuration}
import scala.concurrent.Promise
import scala.util.Success

abstract class PlatformTaskCompanion { self =>

  def schedule[A](pool: ExecutorService)(f: => A): Task[A] = {

    val ec0 = pool match {
      case eces: ExecutionContextExecutorService => eces
      case _ => ExecutionContext.fromExecutorService(pool) // FIXME Is this instantiation costly? Cache it?
    }

    Task(_ => Future(f)(ec0))
  }

  def completeAfter(pool: ScheduledExecutorService, duration: FiniteDuration): Task[Unit] =
    Task.delay {
      val p = Promise[Unit]()
      val runnable =
        new Runnable {
          def run(): Unit =
            p.complete(Success(()))
        }
      pool.schedule(runnable, duration.length, duration.unit)
      Task(_ => p.future)
    }.flatMap(identity)

  implicit val sync: Sync[Task] =
    new TaskSync {
      def schedule[A](pool: ExecutorService)(f: => A) = self.schedule(pool)(f)
    }

  implicit class PlatformTaskOps[T](private val task: Task[T]) {
    def unsafeRun()(implicit ec: ExecutionContext): T =
      Await.result(task.future(), Duration.Inf)
  }

} 
Example 9
Source File: ExecutionContextExecutorServiceBridge.scala    From odinson   with Apache License 2.0 5 votes vote down vote up
package ai.lum.odinson.utils

import java.util.Collections
import java.util.concurrent.{ AbstractExecutorService, TimeUnit }
import scala.concurrent.{ ExecutionContext, ExecutionContextExecutorService }

object ExecutionContextExecutorServiceBridge {
  def apply(ec: ExecutionContext): ExecutionContextExecutorService = ec match {
    case null => throw null
    case eces: ExecutionContextExecutorService => eces
    case other => new AbstractExecutorService with ExecutionContextExecutorService {
      override def prepare(): ExecutionContext = other
      override def isShutdown = false
      override def isTerminated = false
      override def shutdown() = ()
      override def shutdownNow() = Collections.emptyList[Runnable]
      override def execute(runnable: Runnable): Unit = other execute runnable
      override def reportFailure(t: Throwable): Unit = other reportFailure t
      override def awaitTermination(length: Long, unit: TimeUnit): Boolean = false
    }
  }
} 
Example 10
Source File: ExecutionContextScheduler.scala    From reactor-scala-extensions   with Apache License 2.0 5 votes vote down vote up
package reactor.core.scala.scheduler

import java.util.concurrent.Executor

import reactor.core.Disposable
import reactor.core.scheduler.Scheduler.Worker
import reactor.core.scheduler.{Scheduler, Schedulers}

import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, ExecutionContextExecutorService}

class ExecutionContextScheduler private(val scheduler: Scheduler) extends Scheduler {
  override def schedule(task: Runnable): Disposable = scheduler.schedule(task)

  override def createWorker(): Worker = scheduler.createWorker()
}


object ExecutionContextScheduler {
  def apply(executionContext: ExecutionContext): ExecutionContextScheduler = {
    executionContext match {
      case eces: ExecutionContextExecutorService => new ExecutionContextScheduler(Schedulers.fromExecutorService(eces))
      case ece: ExecutionContextExecutor => new ExecutionContextScheduler(Schedulers.fromExecutor(ece))
      case _ => new ExecutionContextScheduler(Schedulers.fromExecutor(new Executor {
        override def execute(command: Runnable): Unit = executionContext.execute(command)
      }))
    }
  }
} 
Example 11
Source File: ThreadUtil.scala    From almond   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package almond.util

import java.lang.Thread.UncaughtExceptionHandler
import java.util.concurrent.{Executors, ThreadFactory}
import java.util.concurrent.atomic.AtomicInteger

import scala.concurrent.{ExecutionContext, ExecutionContextExecutorService}
import scala.util.control.NonFatal

object ThreadUtil {

  // From https://github.com/functional-streams-for-scala/fs2/blob/d47f903bc6bbcdd5d8bc6d573bc7cfd956f0cbb6/core/jvm/src/main/scala/fs2/Strategy.scala#L19-L41
  
  def daemonThreadFactory(threadName: String, exitJvmOnFatalError: Boolean = true): ThreadFactory = new ThreadFactory {
    val defaultThreadFactory = Executors.defaultThreadFactory()
    val idx = new AtomicInteger(0)
    def newThread(r: Runnable) = {
      val t = defaultThreadFactory.newThread(r)
      t.setDaemon(true)
      t.setName(s"$threadName-${idx.incrementAndGet()}")
      t.setUncaughtExceptionHandler(new UncaughtExceptionHandler {
        def uncaughtException(t: Thread, e: Throwable): Unit = {
          System.err.println(s"------------ UNHANDLED EXCEPTION ---------- (${t.getName})")
          e.printStackTrace(System.err)
          if (exitJvmOnFatalError) {
            e match {
              case NonFatal(_) => ()
              case fatal => System.exit(-1)
            }
          }
        }
      })
      t
    }
  }

  def sequentialExecutionContext(): ExecutionContext =
    new SequentialExecutionContext

  def singleThreadedExecutionContext(threadName: String): ExecutionContext =
    ExecutionContext.fromExecutorService(
      Executors.newSingleThreadExecutor(daemonThreadFactory(threadName))
    )

  def attemptShutdownExecutionContext(ec: ExecutionContext): Boolean =
    ec match {
      case _: SequentialExecutionContext =>
        true
      case es: ExecutionContextExecutorService =>
        es.shutdown()
        true
      case _ =>
        false
    }

} 
Example 12
Source File: ExecutionContextExecutorServiceBridge.scala    From firebase4s   with MIT License 5 votes vote down vote up
package com.firebase4s.util

import scala.concurrent.{ExecutionContext, ExecutionContextExecutorService}
import java.util.concurrent.{AbstractExecutorService, TimeUnit}
import java.util.Collections

object ExecutionContextExecutorServiceBridge {
  private[firebase4s] def apply(ec: ExecutionContext): ExecutionContextExecutorService = ec match {
    case null                                  => throw null
    case eces: ExecutionContextExecutorService => eces
    case other =>
      new AbstractExecutorService with ExecutionContextExecutorService {
        override def prepare(): ExecutionContext = other
        override def isShutdown = false
        override def isTerminated = false
        override def shutdown() = ()
        override def shutdownNow() = Collections.emptyList[Runnable]
        override def execute(runnable: Runnable): Unit = other.execute(runnable)
        override def reportFailure(t: Throwable): Unit = other.reportFailure(t)
        override def awaitTermination(length: Long, unit: TimeUnit): Boolean = false
      }
  }
} 
Example 13
Source File: MkResource.scala    From laserdisc   with MIT License 5 votes vote down vote up
package laserdisc
package fs2

import java.util.concurrent.TimeUnit.SECONDS

import cats.effect.{Resource, Sync}

import scala.concurrent.{ExecutionContext, ExecutionContextExecutorService}

object MkResource {
  sealed trait CanShutdown[A] { def shutdown[F[_]](implicit F: Sync[F]): A => F[Unit] }

  final object CanShutdown {
    implicit val canShutdownExecutionContextExecutorService: CanShutdown[ExecutionContextExecutorService] =
      new CanShutdown[ExecutionContextExecutorService] {
        override def shutdown[F[_]](implicit F: Sync[F]): ExecutionContextExecutorService => F[Unit] =
          ec =>
            F.delay {
              ec.shutdown()
              ec.awaitTermination(3, SECONDS)
              ()
            }
      }
  }

  private[laserdisc] final def apply[F[_]: Sync, A](acquire: =>F[A])(implicit A: CanShutdown[A]): Resource[F, A] =
    Resource.make(acquire)(A.shutdown)

  
  @inline final def of[F[_]: Sync](fe: F[ExecutionContextExecutorService]): Resource[F, ExecutionContext] =
    MkResource(fe).widenRight[ExecutionContext]
} 
Example 14
Source File: AsynchronousFileChannel.scala    From zio-nio   with Apache License 2.0 5 votes vote down vote up
package zio.nio.core.channels

import java.io.IOException
import java.nio.channels.{ AsynchronousFileChannel => JAsynchronousFileChannel, FileLock => JFileLock }
import java.nio.file.attribute.FileAttribute
import java.nio.file.OpenOption

import zio.interop.javaz._
import zio.nio.core.file.Path
import zio.nio.core.{ Buffer, ByteBuffer }
import zio.{ Chunk, IO }

import scala.jdk.CollectionConverters._
import scala.concurrent.ExecutionContextExecutorService

class AsynchronousFileChannel(protected val channel: JAsynchronousFileChannel) extends Channel {

  final def force(metaData: Boolean): IO[IOException, Unit] =
    IO.effect(channel.force(metaData)).refineToOrDie[IOException]

  final def lock(position: Long = 0L, size: Long = Long.MaxValue, shared: Boolean = false): IO[Exception, FileLock] =
    effectAsyncWithCompletionHandler[JFileLock](channel.lock(position, size, shared, (), _))
      .map(new FileLock(_))
      .refineToOrDie[Exception]

  final private[nio] def readBuffer(dst: ByteBuffer, position: Long): IO[Exception, Int] =
    dst.withJavaBuffer { buf =>
      effectAsyncWithCompletionHandler[Integer](channel.read(buf, position, (), _))
        .map(_.intValue)
        .refineToOrDie[Exception]
    }

  final def read(capacity: Int, position: Long): IO[Exception, Chunk[Byte]] =
    for {
      b     <- Buffer.byte(capacity)
      count <- readBuffer(b, position)
      a     <- b.array
    } yield Chunk.fromArray(a).take(math.max(count, 0))

  final val size: IO[IOException, Long] =
    IO.effect(channel.size()).refineToOrDie[IOException]

  final def truncate(size: Long): IO[Exception, Unit] =
    IO.effect(channel.truncate(size)).refineToOrDie[Exception].unit

  final def tryLock(position: Long = 0L, size: Long = Long.MaxValue, shared: Boolean = false): IO[Exception, FileLock] =
    IO.effect(new FileLock(channel.tryLock(position, size, shared))).refineToOrDie[Exception]

  final private[nio] def writeBuffer(src: ByteBuffer, position: Long): IO[Exception, Int] =
    src.withJavaBuffer { buf =>
      effectAsyncWithCompletionHandler[Integer](channel.write(buf, position, (), _))
        .map(_.intValue)
        .refineToOrDie[Exception]
    }

  final def write(src: Chunk[Byte], position: Long): IO[Exception, Int] =
    for {
      b <- Buffer.byte(src)
      r <- writeBuffer(b, position)
    } yield r
}

object AsynchronousFileChannel {

  def open(file: Path, options: OpenOption*): IO[Exception, AsynchronousFileChannel] =
    IO.effect(
        new AsynchronousFileChannel(JAsynchronousFileChannel.open(file.javaPath, options: _*))
      )
      .refineToOrDie[Exception]

  def open(
    file: Path,
    options: Set[OpenOption],
    executor: Option[ExecutionContextExecutorService],
    attrs: Set[FileAttribute[_]]
  ): IO[Exception, AsynchronousFileChannel] =
    IO.effect(
        new AsynchronousFileChannel(
          JAsynchronousFileChannel.open(file.javaPath, options.asJava, executor.orNull, attrs.toSeq: _*)
        )
      )
      .refineToOrDie[Exception]
} 
Example 15
Source File: AsynchronousChannelGroup.scala    From zio-nio   with Apache License 2.0 5 votes vote down vote up
package zio.nio.core.channels

import java.io.IOException
import java.nio.channels.{ AsynchronousChannelGroup => JAsynchronousChannelGroup }
import java.nio.channels.spi.{ AsynchronousChannelProvider => JAsynchronousChannelProvider }
import java.util.concurrent.{ ThreadFactory => JThreadFactory }
import java.util.concurrent.TimeUnit

import zio.{ IO, UIO }
import zio.duration.Duration

import scala.concurrent.ExecutionContextExecutorService

object AsynchronousChannelGroup {

  def apply(executor: ExecutionContextExecutorService, initialSize: Int): IO[Exception, AsynchronousChannelGroup] =
    IO.effect(
        new AsynchronousChannelGroup(
          JAsynchronousChannelGroup.withCachedThreadPool(executor, initialSize)
        )
      )
      .refineToOrDie[Exception]

  def apply(
    threadsNo: Int,
    threadsFactory: JThreadFactory
  ): IO[Exception, AsynchronousChannelGroup] =
    IO.effect(
        new AsynchronousChannelGroup(
          JAsynchronousChannelGroup.withFixedThreadPool(threadsNo, threadsFactory)
        )
      )
      .refineToOrDie[Exception]

  def apply(executor: ExecutionContextExecutorService): IO[Exception, AsynchronousChannelGroup] =
    IO.effect(
        new AsynchronousChannelGroup(JAsynchronousChannelGroup.withThreadPool(executor))
      )
      .refineToOrDie[Exception]
}

class AsynchronousChannelGroup(val channelGroup: JAsynchronousChannelGroup) {

  def awaitTermination(timeout: Duration): IO[Exception, Boolean] =
    IO.effect(channelGroup.awaitTermination(timeout.asJava.toMillis, TimeUnit.MILLISECONDS))
      .refineToOrDie[Exception]

  val isShutdown: UIO[Boolean] = IO.effectTotal(channelGroup.isShutdown)

  val isTerminated: UIO[Boolean] = IO.effectTotal(channelGroup.isTerminated)

  val provider: UIO[JAsynchronousChannelProvider] = IO.effectTotal(channelGroup.provider())

  val shutdown: UIO[Unit] = IO.effectTotal(channelGroup.shutdown())

  val shutdownNow: IO[IOException, Unit] =
    IO.effect(channelGroup.shutdownNow()).refineToOrDie[IOException]
} 
Example 16
Source File: AsynchronousFileChannel.scala    From zio-nio   with Apache License 2.0 5 votes vote down vote up
package zio.nio.channels

import java.io.IOException
import java.nio.channels.{ AsynchronousFileChannel => JAsynchronousFileChannel, FileLock => JFileLock }
import java.nio.file.attribute.FileAttribute
import java.nio.file.OpenOption

import zio.interop.javaz._
import zio.nio.core.{ Buffer, ByteBuffer }
import zio.nio.core.channels.FileLock
import zio.nio.core.file.Path
import zio.{ Chunk, IO, Managed, ZIO }

import scala.jdk.CollectionConverters._
import scala.concurrent.ExecutionContextExecutorService

class AsynchronousFileChannel(protected val channel: JAsynchronousFileChannel) extends Channel {

  final def force(metaData: Boolean): IO[IOException, Unit] =
    IO.effect(channel.force(metaData)).refineToOrDie[IOException]

  final def lock(position: Long = 0L, size: Long = Long.MaxValue, shared: Boolean = false): IO[Exception, FileLock] =
    effectAsyncWithCompletionHandler[JFileLock](channel.lock(position, size, shared, (), _))
      .map(FileLock.fromJava(_))
      .refineToOrDie[Exception]

  final private[nio] def readBuffer(dst: ByteBuffer, position: Long): IO[Exception, Int] =
    dst.withJavaBuffer { buf =>
      effectAsyncWithCompletionHandler[Integer](channel.read(buf, position, (), _))
        .map(_.intValue)
        .refineToOrDie[Exception]
    }

  final def read(capacity: Int, position: Long): IO[Exception, Chunk[Byte]] =
    for {
      b     <- Buffer.byte(capacity)
      count <- readBuffer(b, position)
      a     <- b.array
    } yield Chunk.fromArray(a).take(math.max(count, 0))

  final val size: IO[IOException, Long] =
    IO.effect(channel.size()).refineToOrDie[IOException]

  final def truncate(size: Long): IO[Exception, Unit] =
    IO.effect(channel.truncate(size)).refineToOrDie[Exception].unit

  final def tryLock(position: Long = 0L, size: Long = Long.MaxValue, shared: Boolean = false): IO[Exception, FileLock] =
    IO.effect(FileLock.fromJava(channel.tryLock(position, size, shared))).refineToOrDie[Exception]

  final private[nio] def writeBuffer(src: ByteBuffer, position: Long): IO[Exception, Int] =
    src.withJavaBuffer { buf =>
      effectAsyncWithCompletionHandler[Integer](channel.write(buf, position, (), _))
        .map(_.intValue)
        .refineToOrDie[Exception]
    }

  final def write(src: Chunk[Byte], position: Long): IO[Exception, Int] =
    for {
      b <- Buffer.byte(src)
      r <- writeBuffer(b, position)
    } yield r
}

object AsynchronousFileChannel {

  def open(file: Path, options: OpenOption*): Managed[Exception, AsynchronousFileChannel] = {
    val open = ZIO
      .effect(new AsynchronousFileChannel(JAsynchronousFileChannel.open(file.javaPath, options: _*)))
      .refineToOrDie[Exception]

    Managed.make(open)(_.close.orDie)
  }

  def openWithExecutor(
    file: Path,
    options: Set[_ <: OpenOption],
    executor: Option[ExecutionContextExecutorService],
    attrs: Set[FileAttribute[_]] = Set.empty
  ): Managed[Exception, AsynchronousFileChannel] = {
    val open = ZIO
      .effect(
        new AsynchronousFileChannel(
          JAsynchronousFileChannel.open(file.javaPath, options.asJava, executor.orNull, attrs.toSeq: _*)
        )
      )
      .refineToOrDie[Exception]

    Managed.make(open)(_.close.orDie)
  }
}