mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
fix: nil pointer when sonyflake is not properly configured
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/jsiebens/ionscale/internal/service"
|
"github.com/jsiebens/ionscale/internal/service"
|
||||||
"github.com/jsiebens/ionscale/internal/stunserver"
|
"github.com/jsiebens/ionscale/internal/stunserver"
|
||||||
"github.com/jsiebens/ionscale/internal/templates"
|
"github.com/jsiebens/ionscale/internal/templates"
|
||||||
|
"github.com/jsiebens/ionscale/internal/util"
|
||||||
"github.com/labstack/echo-contrib/echoprometheus"
|
"github.com/labstack/echo-contrib/echoprometheus"
|
||||||
"github.com/labstack/echo-contrib/pprof"
|
"github.com/labstack/echo-contrib/pprof"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@@ -53,6 +54,8 @@ func Start(ctx context.Context, c *config.Config) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
util.EnsureIDProvider()
|
||||||
|
|
||||||
derpMap, err := derp.LoadDERPSources(c)
|
derpMap, err := derp.LoadDERPSources(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warn("not all derp sources are read successfully", zap.Error(err))
|
logger.Warn("not all derp sources are read successfully", zap.Error(err))
|
||||||
|
|||||||
+50
-12
@@ -1,8 +1,10 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/sony/sonyflake"
|
"github.com/sony/sonyflake"
|
||||||
|
"go.uber.org/zap"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -11,30 +13,66 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
sf *sonyflake.Sonyflake
|
sf provider
|
||||||
sfOnce sync.Once
|
sfOnce sync.Once
|
||||||
)
|
)
|
||||||
|
|
||||||
func NextID() uint64 {
|
func NextID() uint64 {
|
||||||
ensureProvider()
|
EnsureIDProvider()
|
||||||
id, _ := sf.NextID()
|
id, err := sf.NextID()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureProvider() {
|
type provider interface {
|
||||||
sfOnce.Do(func() {
|
NextID() (uint64, error)
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
func machineID() func() (uint16, error) {
|
||||||
envMachineID := os.Getenv("IONSCALE_MACHINE_ID")
|
envMachineID := os.Getenv("IONSCALE_MACHINE_ID")
|
||||||
if len(envMachineID) != 0 {
|
if len(envMachineID) != 0 {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"math/big"
|
"math/big"
|
||||||
@@ -31,6 +32,15 @@ func RandUint64(n uint64) uint64 {
|
|||||||
return val.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) {
|
func RandomBytes(size int) ([]byte, error) {
|
||||||
buf := make([]byte, size)
|
buf := make([]byte, size)
|
||||||
if _, err := rand.Read(buf); err != nil {
|
if _, err := rand.Read(buf); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user