在方法的后台运行fs2.Stream?

时间:2019-12-24 03:53:08

标签: scala functional-programming scala-cats fs2

我只是在学习FP,所以也许我做错了。

使用cats,cats-effects,fs2,fs2-io。

以下代码将port作为参数,然后在给定端口上创建连接到127.0.0.1的服务器套接字和客户端套接字。

我需要此函数返回的是分配的服务器套接字端口。

问题:在方法的后台运行fs2.Stream时,我该怎么做Int => F[Int]

我正在使用cats-effects IOApp运行该程序。

我的代码:

trait TCP[F[_]] {
    def createTunnel(localPort: Int): F[TCP.CreatedTunnel]
}
object TCP {
    implicit def apply[F[_]](implicit ev: TCP[F]): TCP[F] = ev

    final case class CreatedTunnel(remotePort: Int) extends AnyVal

    def impl[F[_]: Applicative : ContextShift : ConcurrentEffect](socketGroup: SocketGroup): TCP[F] = new TCP[F] {

        override def createTunnel(localPort: Int): F[CreatedTunnel] = {

            val localBindAddress = Deferred[F, InetSocketAddress]

            val stream = Stream
                .eval(socketGroup.serverWithLocalAddress[F](new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0)))
            .flatMap {
                  case Left(localAddress) =>
                      Stream.eval_(localBindAddress.flatMap(_.complete(localAddress)))
                  case Right(serverSocket) =>
                      Stream.resource(serverSocket.map { socket =>
                          Stream
                              .eval(socketGroup.client[F](new InetSocketAddress("127.0.0.1", localPort)))
                          .map { clientSocket =>
                                clientSocket.reads(1024).through(socket.writes())
                                socket.reads(1024).through(clientSocket.writes())
                            }
                      })
              }

            // -------------------------------------------
            // (!!!) I need to return this, 
            //       but i need to run stream above first
            // -------------------------------------------
            localBindAddress.map(_.get.map(addr => TCP.CreatedTunnel(addr.getPort)))

        }
    }
}

0 个答案:

没有答案