Echo#
Info
This example is for Challenge #1: Echo
It demonstrates how to create a simple node that echoes messages back to the sender
import zio.json.{JsonEncoder, JsonDecoder}
import zio.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
case class Echo(echo: String) derives JsonDecoder // (1)!
case class EchoOk(echo: String) derives JsonEncoder // (2)!
- All input messages need a way to decode them. We use
zio-jsonto deriveJsonDecoder - Outgoing messages need a
JsonEncoder. If a message needs to be sent by one node and received by another, it needs aJsonCodecinstance which combines bothJsonEncoderandJsonDecoder
Note
Maelstrom documentation has information about core fields such as msg_id, type and in_reply_to.
We don't need to define these fields in our message classes as they are handled by the framework automatically.
A node is defined by extending the MaelstromNode trait and providing a program value. The program value is a ZIO effect that defines the behavior of the node. The receive function is used to define a handler for incoming request messages.
object Main extends MaelstromNode { // (1)!
val program = receive[Echo](msg => reply(EchoOk(msg.echo))) // (2)!
}
- Note that definition needs to be an
objectfor it to be runnable replyis a function that sends a reply to the sender of the message. The correlation between the request and reply is handled by the framework, so we don't need to worry about it
Using maelstrom DSL functions such as receive and reply requires MaelstromRuntime which is automatically provided by MaelstromNode.
Note
Source code for this example can be found on Github