Skip to content

Echo#

Info

This example is for Challenge #1: Echo

It demonstrates how to create a simple node that echoes messages back to the sender

Imports
import zio.json.{JsonEncoder, JsonDecoder}
import zio.{ZIOAppDefault, ZIO}
import com.bilalfazlani.zioMaelstrom.*

Here, we define the protocol of the node. It includes messages which the node can handle and messages it can send. Create data classes only for the body part of a maelstrom message. The top level fields (i.e. src, dest) are handled by the library

Message definitions
case class Echo(echo: String, msg_id: MessageId) extends NeedsReply // (1)!
    derives JsonDecoder // (2)!

case class EchoOk(echo: String, in_reply_to: MessageId, `type`: String = "echo_ok")
    extends Sendable,
      Reply             // (3)!
    derives JsonEncoder // (4)!
  1. Every messages that needs an acknowledgement or reply should extend NeedsReply
  2. All input messages need a way to decode them. We use zio-json to derive JsonDecoder
  3. Messages that need to be sent out need to extend from Sendable. If they are a reply to some other message, they should also extend from Reply
  4. Outgoing messages need JsonEncoders

Note

Refer to Maelstrom documentation for more information on the standard message fields like msg_id, type, in_reply_to etc

This is the Node definition. It defines the behavior of the node and is a typical ZIO application. We use the recieve function to define a handler for incoming request messages

Node application
object Main extends ZIOAppDefault {

  val echoHandler: ZIO[MaelstromRuntime, Nothing, Unit] =
    receive[Echo](msg => reply(EchoOk(echo = msg.echo, in_reply_to = msg.msg_id))) // (1)!

  val run = echoHandler.provide(MaelstromRuntime.live)
}
  1. reply is a function that sends a reply to the sender of the message. It takes a Sendable & Reply message as an argument. You can only call reply on messages that extend NeedsReply

Using maelstrom DSL functions such as receive and reply requires MaelstromRuntime which can be provided as a ZLayer to the application as shown above

Note

Source code for this example can be found on Github