feat: add tenant-aware IM management console
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
package imtenant
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
sf "github.com/tinode/snowflake"
|
||||
)
|
||||
|
||||
const defaultSnowflakeWorkerID = 1023
|
||||
|
||||
var (
|
||||
snowflakeOnce sync.Once
|
||||
snowflakeGen *sf.SnowFlake
|
||||
snowflakeErr error
|
||||
)
|
||||
|
||||
// NextSnowflakeID returns an unencrypted Snowflake ID suitable for IM BIGINT keys.
|
||||
func NextSnowflakeID(ctx context.Context) (int64, error) {
|
||||
snowflakeOnce.Do(func() {
|
||||
workerID := g.Cfg().MustGet(ctx, "imDirectDb.snowflakeWorkerId", defaultSnowflakeWorkerID).Int()
|
||||
if value := os.Getenv("IM_DIRECT_DB_SNOWFLAKE_WORKER_ID"); value != "" {
|
||||
workerID, snowflakeErr = strconv.Atoi(value)
|
||||
if snowflakeErr != nil {
|
||||
snowflakeErr = fmt.Errorf("invalid IM_DIRECT_DB_SNOWFLAKE_WORKER_ID: %w", snowflakeErr)
|
||||
return
|
||||
}
|
||||
}
|
||||
if workerID < 0 || workerID > 1023 {
|
||||
snowflakeErr = fmt.Errorf("IM Snowflake worker ID must be between 0 and 1023")
|
||||
return
|
||||
}
|
||||
snowflakeGen, snowflakeErr = sf.NewSnowFlake(uint32(workerID))
|
||||
})
|
||||
if snowflakeErr != nil {
|
||||
return 0, snowflakeErr
|
||||
}
|
||||
id, err := snowflakeGen.Next()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if id == 0 || id > uint64(^uint64(0)>>1) {
|
||||
return 0, fmt.Errorf("generated invalid IM Snowflake ID")
|
||||
}
|
||||
return int64(id), nil
|
||||
}
|
||||
Reference in New Issue
Block a user