私は scalaz-stream と特に scalaz.stream.tcp の両方に非常に慣れていません。私は自分の教育目的で非常に単純なサーバーを作ろうとしています。リクエストをコマンドに解析し、それらを実行してレスポンスを生成し、レスポンスをクライアントに書き戻します。私が問題を抱えている部分は、受信した各コマンドを標準出力に記録したいということです。
tcp.server に渡す内部プロセスは次のとおりです。
def inner: Process[tcp.Connection, Unit] = {
val requests: Process[Connection, String] = tcp.reads(1024) pipe text.utf8Decode
val cmds: Process[Connection, Command] = requests.map(parseRequest)
val header: Process[Task, ByteVector] = Process("HEADER\n").pipe(text.utf8Encode)
val loggedCmds: Process[Connection, Command] = cmds.map { cmd =>
println(cmd.toString)
cmd
}
val results: Process[Connection, Process[Task, ByteVector]] = loggedCmds.map(_.execute)
val processedRequests: Process[Connection, Unit] = results.flatMap(result => tcp.writes(tcp.lift(header ++ result)))
processedRequests
}
(私はどこにでも型を指定する習慣はありません。物事を把握するためにそうしました。それらを削除する予定です。)
上記のコードは、実際には正しくコンパイルおよび実行されますが、あまりクリーンでも慣用的でもないように感じます。具体的には、loggedCmds の部分に不満があります。.observer または writer.logged/mapW/drainW を使用して、io.stdOutLines を使用したかったのですが、何を試しても、型を正しく並べることができなかったようです。タスクと接続の間で常に型の競合が発生していました。tcp.lift は入力ストリームには役立つようですが、シンクには機能しないようです。LoggedCmds 部分を実行するためのよりクリーンな/より良い方法はありますか (FWIW: 上記のコードの修正または改善を受け入れます)。
結果を io.stdOutLines 経由で stdout に送るだけであれば問題はありません (例で見たように、その場合は「スルー」が機能するようです)。ストリームを io.stdOutLines に送信し、引き続きストリームを使用してクライアントに応答します。