Give your stack server process a name, and make sure it is accessible by that name in IEx.
Add the API to your stack module (the functions that wrap the GenServer calls).
Implement the terminate callback in your stack handler. Use IO.puts to report the arguments it receives.
Try various ways of terminating your server. For example, popping an empty stack will raise an exception. You might add code that calls System.halt(n) if the push handler receives a number less than 10. (This will let you generate different return codes.) Use your imagination to try different scenarios.
An OTP GenServer is just a regular Elixir process in which the message handling has been abstracted out. The GenServer behavior defines a message loop internally and maintains a state variable. That message loop then calls out to various functions that we define in our server module: handle_call, handle_cast, and so on.
We also saw that GenServer provides fairly detailed tracing of the messages received and responses sent by our server modules.
Finally, we wrapped our message-based API in module functions, which gives our users a cleaner interface and decouples them from our implementation.
But we still have an issue if our server crashes. We’ll deal with this in the next chapter, when we look at supervisors.