You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
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)
The text was updated successfully, but these errors were encountered:
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
usesyaegi
in order to interprettemplate.go
files that generate code. As a result, there is no requirement to continuously rungo 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 asCreateGlobalApplicationCommands
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 ofidentify
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
Disclaimer: Users actually send requests to the REST API to trigger interactions, but this is simplified for the sake of focus.
Task
The text was updated successfully, but these errors were encountered: