fix: nil pointer when sonyflake is not properly configured

This commit is contained in:
Johan Siebens
2025-04-26 09:33:25 +02:00
parent 828e0c920b
commit a2fd56be89
3 changed files with 64 additions and 13 deletions
+3
View File
@@ -17,6 +17,7 @@ import (
"github.com/jsiebens/ionscale/internal/service"
"github.com/jsiebens/ionscale/internal/stunserver"
"github.com/jsiebens/ionscale/internal/templates"
"github.com/jsiebens/ionscale/internal/util"
"github.com/labstack/echo-contrib/echoprometheus"
"github.com/labstack/echo-contrib/pprof"
"github.com/labstack/echo/v4"
@@ -53,6 +54,8 @@ func Start(ctx context.Context, c *config.Config) error {
return err
}
util.EnsureIDProvider()
derpMap, err := derp.LoadDERPSources(c)
if err != nil {
logger.Warn("not all derp sources are read successfully", zap.Error(err))
+50 -12
View File
@@ -1,8 +1,10 @@
package util
import (
"errors"
"fmt"
"github.com/sony/sonyflake"
"go.uber.org/zap"
"net"
"os"
"strconv"
@@ -11,30 +13,66 @@ import (
)
var (
sf *sonyflake.Sonyflake
sf provider
sfOnce sync.Once
)
func NextID() uint64 {
ensureProvider()
id, _ := sf.NextID()
EnsureIDProvider()
id, err := sf.NextID()
if err != nil {
panic(err)
}
return id
}
func ensureProvider() {
sfOnce.Do(func() {
sfInstance, err := sonyflake.New(sonyflake.Settings{
MachineID: machineID(),
StartTime: time.Date(2022, 05, 01, 00, 0, 0, 0, time.UTC),
})
if err != nil {
panic("unable to initialize sonyflake: " + err.Error())
type provider interface {
NextID() (uint64, error)
}
sf = sfInstance
type errorProvider struct {
err error
}
func (e errorProvider) NextID() (uint64, error) {
return 0, fmt.Errorf("unable to generate ID, sonyflake not configured properly: %w", e.err)
}
func EnsureIDProvider() {
sfOnce.Do(func() {
sf = createIDProvider()
})
}
func createIDProvider() provider {
startTime := time.Date(2022, 05, 01, 00, 0, 0, 0, time.UTC)
sfInstance, err := sonyflake.New(sonyflake.Settings{
MachineID: machineID(),
StartTime: startTime,
})
if err != nil && errors.Is(err, sonyflake.ErrNoPrivateAddress) {
id := RandUint16()
zap.L().Warn("failed to generate sonyflake machine id from private ip address, using a random machine id", zap.Uint16("id", id))
sfInstance, err = sonyflake.New(sonyflake.Settings{
MachineID: func() (uint16, error) { return id, nil },
StartTime: startTime,
})
if err != nil {
return errorProvider{err}
}
}
if err != nil {
return errorProvider{err}
}
return sfInstance
}
func machineID() func() (uint16, error) {
envMachineID := os.Getenv("IONSCALE_MACHINE_ID")
if len(envMachineID) != 0 {
+10
View File
@@ -4,6 +4,7 @@ import (
"crypto/md5"
"crypto/rand"
"crypto/rsa"
"encoding/binary"
"encoding/hex"
"encoding/json"
"math/big"
@@ -31,6 +32,15 @@ func RandUint64(n uint64) uint64 {
return val.Uint64()
}
func RandUint16() uint16 {
var randomBytes [2]byte
_, err := rand.Read(randomBytes[:])
if err != nil {
panic(err)
}
return binary.BigEndian.Uint16(randomBytes[:])
}
func RandomBytes(size int) ([]byte, error) {
buf := make([]byte, size)
if _, err := rand.Read(buf); err != nil {