zio.http.netty.NettyChannel.scala Maven / Gradle / Ivy
/*
* Copyright 2021 - 2023 Sporta Technologies PVT LTD & the ZIO HTTP contributors.
*
* 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 zio.http.netty
import zio._
import zio.stacktracer.TracingImplicits.disableAutoTrace
import io.netty.channel.{Channel => JChannel, ChannelFuture => JChannelFuture}
private[netty] final case class NettyChannel[-A](
private val channel: JChannel,
private val convert: A => Any,
) {
self =>
private def run(await: Boolean)(run: JChannel => JChannelFuture)(implicit trace: Trace): Task[Unit] = {
if (await) {
NettyFutureExecutor.executed(run(channel))
} else {
ZIO.attempt(run(channel): Unit)
}
}
def autoRead(flag: Boolean)(implicit trace: Trace): UIO[Unit] =
ZIO.succeed(channel.config.setAutoRead(flag): Unit)
def awaitClose(implicit trace: Trace): UIO[Unit] = ZIO.async[Any, Nothing, Unit] { register =>
channel.closeFuture().addListener((_: JChannelFuture) => register(ZIO.unit))
()
}
def close(await: Boolean = false)(implicit trace: Trace): Task[Unit] =
run(await) { _.close() }
def contramap[A1](f: A1 => A): NettyChannel[A1] = copy(convert = convert.compose(f))
def flush(implicit trace: Trace): Task[Unit] = ZIO.attempt(channel.flush(): Unit)
def id(implicit trace: Trace): String = channel.id().asLongText()
def isAutoRead(implicit trace: Trace): UIO[Boolean] = ZIO.succeed(channel.config.isAutoRead)
def read(implicit trace: Trace): UIO[Unit] = ZIO.succeed(channel.read(): Unit)
def write(msg: A, await: Boolean = false)(implicit trace: Trace): Task[Unit] =
run(await) {
_.write(convert(msg))
}
def writeAndFlush(msg: => A, await: Boolean = true)(implicit trace: Trace): Task[Unit] =
run(await) { ch =>
ch.writeAndFlush(convert(msg))
}
}
private[netty] object NettyChannel {
def make[A](channel: JChannel): NettyChannel[A] = NettyChannel(channel, identity)
}