A colleague of mine, Vlad Nicu, is developing a Telegram bot to offer information about cryptocurrencies (price, etc). After talking with him, I had the idea of writing a bot to connect to a MUD (Multi User Dungeon) using Telegram. When I was young, I spent a lot of time playing with this type of online games and I thought it'd be fun to develop something similar.
I decided to use Golang to practice a little with this language and its goroutines. I think it has a lot of things that could be improved, but, undoubtedly, concurrency is its strongest feature. From my point of view, sometimes people abuse of channels and goroutines. I have seen a lot of examples of problems that could be resolved only with function calls, without all the goroutines system.
The source code of midgaard_bot is available under GPLv3 license.
When the bot starts, it launchs a new goroutine that listens messages that arrive from Telegram. When a message arrives, it checks if there is an open session for the chat owner of the message. If it's the first message from that chat, propably there won't be an open session.
In that case, the bot launchs a new goroutine for connecting with the MUD by telnet and serving as a connector between Telegram and the game.
For checking in which time the telnet connection has finished sending a complete message, and then send it to Telegram, I had to implement a buffer to receive data from the MUD and use a 500 milliseconds timeout. After the timeout, in theory the message is complete so it can be sent. I know it isn't a magical solution, but for local connections it runs so well.
When the message is complete, we send it to a specific goroutine that receives messages from open sessions and forwards them to Telegram.
During the development, a funny thing happened to me, and that makes me think about how goroutines really work. The goroutine in charge of an open session wrote a message to a channel and, after that, it got suspended. The problem was that I didn't develop the code to read that channel yet, and Go channels block the execution.
I thought Go channels run in a similar way than messages work in Erlang. In Erlang, a process send messages asynchronously, and the execution continues independently. But in Golang is different, channels aren't pipes, are meeting points for goroutines. If you put a message in a channel, you are blocked until another goroutine reads that channel and releases the goroutine that has written that message.
Curious things that concurrency has when you use these tools.
Midgaard Bot is unfinished and I'm not interested in continue with the development, my goal was to check if I could connect with the MUD using Telegram, and that is already achieved. But if someone wants to continue, you have everything necessary in the repo.