Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Hot Reload Guide #46

Closed
5 tasks
switchupcb opened this issue Dec 3, 2022 · 0 comments
Closed
5 tasks

add Hot Reload Guide #46

switchupcb opened this issue Dec 3, 2022 · 0 comments
Labels
enhancement New feature or request

Comments

@switchupcb
Copy link
Owner

switchupcb commented Dec 3, 2022

Introduction

Creating or debugging a Discord Bot in Go can be time consuming due to the need to go build after every change. Interpreted languages (i.e Python, JavaScript) don't require building since the code is interpreted as it's required (using a Just In Time Compiler). Using Go (and Disgo) provides an increase to code velocity and performance due to ease of concurrency usage and compilation. If we can figure out a way to Hot Reload during the build process, code iteration that involves the build process will be handled without effort. This provides a better developer experience to the end user (developer).

What is Hot Reloading?

Live Reloading reloads or refreshes the entire app when a file changes. Hot Reloading only refreshes the files that were changed without losing the state of the app. For more information, read What is the difference between Hot Reloading and Live Reloading?.

How can you Hot Reload in Go?

The first option is to use an interpreter. As an example, copygen uses yaegi in order to interpret template.go files that generate code. As a result, there is no requirement to continuously run go build during the code generation process. Unfortunately, none of the available interpreters for Go support third party modules (to the standard Go library; i.e Disgo). yaegi has yet to review my pull request for Go module support in traefik/yaegi#1265 (comment). gomacro does not support 3rd party imports cross-platform (tracked in cosmos72/gomacro#121).

This approach is also not performant.

The alternative option is to selectively build code as it changes. This is possible with a Live Reload module such as air. However, live reloading implies that the entire application is restarted, which means that — in the context of a single binary — existing WebSocket Connections would be lost. Thus, a Go Discord Bot that creates function or maintains a state using a single binary would not be possible. Instead, one must create multiple binaries and only hot reload them when a state is not required.

What is a cluster?

A computer cluster describes a group of computers (servers) running together to act as a single system. Modern software clusters involve containers (such as Docker or Podman) and container orchestrators (such as Kubernetes or Nomad) in order to maintain clusters (of services). Clusters are typically used in software that involves microservices.

How to Hot Deploy a Discord Bot

Using the information above, a system that supports Hot Reloading for Go Discord Bot's can be architected.

Design

Go's compilation allows the creation of single-file executables. Such that a service can be run from a computer using ./service. The hot reload guide will demonstrate how to implement Hot Reloading for a Discord Bot that uses Application Commands and responds to Interactions (over the WebSocket Connection) using 3 services.

Commands (State)

A .go file (compiled to a binary) will be used to maintain the Bot's Application Commands. As requests such as CreateGlobalApplicationCommands are idempodent, this can be demonstrated in a manner that encourages the end user (developer) to create stateful Application Command Requests for the initialization of the program (or to update available commands).

WebSocket (Client, Server)

A .go file (compiled to a binary) will be used to maintain the Bot's WebSocket Connection to the Discord Gateway. THIS SERVICE MUST NOT BE RELOADED. Otherwise, the Bot will disconnect from the Discord Gateway and require reconnection. Disgo will handle this reconnection, but given that Discord maintains a daily rate limit for the amount of identify send events, it's not recommended to continuously disconnect and reconnect from the Gateway. Therefore, this service will be unmodified throughout the example.

An additional service must be created to handle interactions, such that interaction handling is hot reloadable.

Response (Client)

A .go file (compiled to a binary) will be used to handle the Bot's Interactions using requests (which don't require connections to the Discord Gateway). This implementation is a complement to the WebSocket Service, which can't be reloaded. As a result, this service will be reloaded (frequently) to change how a bot handle's interactions.

The interaction handler must retrieve incoming data from Discord from the WebSocket service, which is running from another application. As a result, the WebSocket server must serve incoming from data over the network to the Interaction Handler service, which then sends the Interaction Response to Discord. This means that the WebSocket Client must also implement a server to serve the Response service data from Discord.

Diagram

image

Disclaimer: Users actually send requests to the REST API to trigger interactions, but this is simplified for the sake of focus.

Task

  • Hot Reload Concept Documentation
  • Hot Reload Example
    • Set up a localhost "cluster"
    • Run all binaries
    • Change code to Interaction Handler
    • Reload Interaction Service
    • Change code to command
    • Reload Command Service
  • (Go) Hot Reload Service: Commands (State)
  • (Go) Hot Reload Service: WebSocket (Discord Client, Response Server)
  • (Go) Hot Reload Service: Response (Client)
@switchupcb switchupcb added the enhancement New feature or request label Dec 3, 2022
This was referenced Dec 3, 2022
Repository owner locked and limited conversation to collaborators Jul 8, 2023
@switchupcb switchupcb converted this issue into discussion #66 Jul 8, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant