Skip to content

Instantly share code, notes, and snippets.

@Benricheson101
Created February 25, 2022 02:23
Show Gist options
  • Save Benricheson101/97de1647f0604dfb5835a8c2afabf40e to your computer and use it in GitHub Desktop.
Save Benricheson101/97de1647f0604dfb5835a8c2afabf40e to your computer and use it in GitHub Desktop.
discordgo zero downtime restart
package main
import (
"flag"
"fmt"
"os"
"os/signal"
"reflect"
"sync/atomic"
"syscall"
"unsafe"
"github.com/bwmarrin/discordgo"
)
var (
sid string
seq int64
)
func init() {
flag.StringVar(&sid, "sid", "", "")
flag.Int64Var(&seq, "seq", 0, "")
flag.Parse()
}
func main() {
s, _ := discordgo.New("Bot " + os.Getenv("DISCORD_TOKEN"))
if sid != "" && seq != 0 {
setField(s, "sequence", &seq)
setField(s, "sessionID", sid)
}
s.AddHandler(func(se *discordgo.Session, e *discordgo.Event) {
fmt.Println(e.Type)
})
s.Open()
sig := make(chan os.Signal)
signal.Notify(sig, syscall.SIGINT)
<-sig
fmt.Printf("to resume: go run cmd/resume/main.go -seq %v -sid %v\n", getSequence(s), getField(s, "sessionID").String())
}
func setField(s interface{}, fieldName string, newVal interface{}) {
val := reflect.ValueOf(s)
field := reflect.Indirect(val).FieldByName(fieldName)
ptrToField := unsafe.Pointer(field.UnsafeAddr())
settableField := reflect.NewAt(field.Type(), ptrToField).Elem()
n := reflect.ValueOf(newVal)
settableField.Set(n)
}
func getField(s interface{}, fieldName string) reflect.Value {
val := reflect.ValueOf(s)
return reflect.Indirect(val).FieldByName(fieldName)
}
func getSequence(s *discordgo.Session) int64 {
field := getField(s, "sequence")
ptr := (*int64)(unsafe.Pointer(field.Pointer()))
return atomic.LoadInt64(ptr)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment