Skip to content

Commit

Permalink
Better representation for SelectionKey operations (#28)
Browse files Browse the repository at this point in the history
* Better representation for SelectionKey operations #21

* Revert "Better representation for SelectionKey operations #21"

This reverts commit 4b2ee05.

* Better representation for SelectionKey operations #21

* formatting and validOps for SelectableChannel

* merge upstream changes
  • Loading branch information
Vladimir Shevtsov authored and quelgar committed Aug 17, 2019
1 parent 431c258 commit a805003
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 15 deletions.
21 changes: 16 additions & 5 deletions src/main/scala/zio/nio/channels/SelectableChannel.scala
Expand Up @@ -9,6 +9,7 @@ import java.nio.channels.{
SocketChannel => JSocketChannel
}

import zio.nio.channels.SelectionKey.Operation
import zio.nio.channels.spi.SelectorProvider
import zio.nio.{ Buffer, SocketAddress, SocketOption }
import zio.{ IO, UIO }
Expand All @@ -20,21 +21,31 @@ trait SelectableChannel extends Channel {
final val provider: UIO[SelectorProvider] =
IO.effectTotal(new SelectorProvider(channel.provider()))

final val validOps: UIO[Int] =
final val validOps: UIO[Set[Operation]] =
IO.effectTotal(channel.validOps())
.map(Operation.fromInt(_))

final val isRegistered: UIO[Boolean] =
IO.effectTotal(channel.isRegistered())

final def keyFor(sel: Selector): UIO[Option[SelectionKey]] =
IO.effectTotal(Option(channel.keyFor(sel.selector)).map(new SelectionKey(_)))

final def register(sel: Selector, ops: Int, att: Option[AnyRef]): IO[IOException, SelectionKey] =
IO.effect(new SelectionKey(channel.register(sel.selector, ops, att.orNull)))
final def register(sel: Selector, ops: Set[Operation], att: Option[AnyRef]): IO[IOException, SelectionKey] =
IO.effect(new SelectionKey(channel.register(sel.selector, Operation.toInt(ops), att.orNull)))
.refineToOrDie[IOException]

final def register(sel: Selector, ops: Int): IO[IOException, SelectionKey] =
IO.effect(new SelectionKey(channel.register(sel.selector, ops))).refineToOrDie[IOException]
final def register(sel: Selector, ops: Set[Operation]): IO[IOException, SelectionKey] =
IO.effect(new SelectionKey(channel.register(sel.selector, Operation.toInt(ops))))
.refineToOrDie[IOException]

final def register(sel: Selector, op: Operation, att: Option[AnyRef]): IO[IOException, SelectionKey] =
IO.effect(new SelectionKey(channel.register(sel.selector, op.intVal, att.orNull)))
.refineToOrDie[IOException]

final def register(sel: Selector, op: Operation): IO[IOException, SelectionKey] =
IO.effect(new SelectionKey(channel.register(sel.selector, op.intVal)))
.refineToOrDie[IOException]

final def configureBlocking(block: Boolean): IO[IOException, Unit] =
IO.effect(channel.configureBlocking(block)).unit.refineToOrDie[IOException]
Expand Down
35 changes: 28 additions & 7 deletions src/main/scala/zio/nio/channels/SelectionKey.scala
Expand Up @@ -14,6 +14,23 @@ object SelectionKey {
case e: CancelledKeyException => e
}

sealed abstract class Operation(val intVal: Int)

object Operation {

final case object Read extends Operation(JSelectionKey.OP_READ)
final case object Write extends Operation(JSelectionKey.OP_WRITE)
final case object Connect extends Operation(JSelectionKey.OP_CONNECT)
final case object Accept extends Operation(JSelectionKey.OP_ACCEPT)

final val fullSet: Set[Operation] = Set(Read, Write, Connect, Accept)

final def fromInt(ops: Int): Set[Operation] =
fullSet.filter(op => (ops & op.intVal) != 0)

final def toInt(set: Set[Operation]): Int =
set.foldLeft(0)((ops, op) => ops | op.intVal)
}
}

class SelectionKey(private[nio] val selectionKey: JSelectionKey) {
Expand All @@ -32,16 +49,20 @@ class SelectionKey(private[nio] val selectionKey: JSelectionKey) {
final val cancel: UIO[Unit] =
IO.effectTotal(selectionKey.cancel())

final val interestOps: IO[CancelledKeyException, Int] =
IO.effect(selectionKey.interestOps()).refineToOrDie[CancelledKeyException]
final val interestOps: IO[CancelledKeyException, Set[Operation]] =
IO.effectTotal(selectionKey.interestOps())
.map(Operation.fromInt(_))
.refineToOrDie[CancelledKeyException]

final def interestOps(ops: Int): IO[CancelledKeyException, SelectionKey] =
IO.effect(selectionKey.interestOps(ops))
.map(new SelectionKey(_))
final def interestOps(ops: Set[Operation]): IO[CancelledKeyException, Unit] =
IO.effect(selectionKey.interestOps(Operation.toInt(ops)))
.unit
.refineToOrDie[CancelledKeyException]

final val readyOps: IO[CancelledKeyException, Int] =
IO.effect(selectionKey.readyOps()).refineToOrDie[CancelledKeyException]
final val readyOps: IO[CancelledKeyException, Set[Operation]] =
IO.effect(selectionKey.readyOps())
.map(Operation.fromInt(_))
.refineToOrDie[CancelledKeyException]

final def isReadable: IO[CancelledKeyException, Boolean] =
IO.effect(selectionKey.isReadable()).refineOrDie(JustCancelledKeyException)
Expand Down
7 changes: 4 additions & 3 deletions src/test/scala/zio/nio/channels/SelectorSuite.scala
@@ -1,10 +1,11 @@
package zio.nio.channels

import java.nio.channels.{ CancelledKeyException, SelectionKey => JSelectionKey, SocketChannel => JSocketChannel }
import java.nio.channels.{ CancelledKeyException, SocketChannel => JSocketChannel }

import testz.{ Harness, assert }
import zio._
import zio.clock.Clock
import zio.nio.channels.SelectionKey.Operation
import zio.nio.{ Buffer, SocketAddress }

object SelectorSuite extends DefaultRuntime {
Expand Down Expand Up @@ -36,7 +37,7 @@ object SelectorSuite extends DefaultRuntime {
clientOpt <- channel.accept
client = clientOpt.get
_ <- client.configureBlocking(false)
_ <- client.register(selector, JSelectionKey.OP_READ)
_ <- client.register(selector, Operation.Read)
} yield ()
} *>
IO.whenM(safeStatusCheck(key.isReadable)) {
Expand All @@ -62,7 +63,7 @@ object SelectorSuite extends DefaultRuntime {
channel <- ServerSocketChannel.open
_ <- channel.bind(address)
_ <- channel.configureBlocking(false)
_ <- channel.register(selector, JSelectionKey.OP_ACCEPT)
_ <- channel.register(selector, Operation.Accept)
buffer <- Buffer.byte(256)
_ <- started.succeed(())

Expand Down

0 comments on commit a805003

Please sign in to comment.