Skip to content

Commit

Permalink
Merge pull request #4 from storage-lock/dev
Browse files Browse the repository at this point in the history
feat: 优化OwnerIdGenerator及增加单元测试、API示例代码
  • Loading branch information
CC11001100 authored Aug 13, 2023
2 parents 4db648a + e7981cf commit cf266da
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 8 deletions.
16 changes: 16 additions & 0 deletions examples/owner_id_generator/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

import (
"fmt"
storage_lock "github.com/storage-lock/go-storage-lock"
)

func main() {

generator := storage_lock.NewOwnerIdGenerator()
ownerId := generator.GenOwnerId()
fmt.Println(ownerId)
// Output:
// storage-lock-owner-id-DESKTOP-PL5RI7C-72c2cd2add88b29799e2f2646be16131-1-541201dd0eee40bba0f956ddce427f7c

}
23 changes: 15 additions & 8 deletions owner_id_generator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package storage_lock

import (
"crypto/md5"
"encoding/hex"
"fmt"
goroutine_id "github.com/golang-infrastructure/go-goroutine-id"
"github.com/storage-lock/go-utils"
Expand All @@ -9,13 +11,14 @@ import (
"strings"
)

// OwnerIdGenerator 当没有指定锁的持有者的ID的时候,自动生成一个ID
// OwnerIdGenerator 可以使用这个工具类来生成全局唯一的OwnerID
// 1. 要满足全局唯一不重复
// 2. 可读性尽量好一些
type OwnerIdGenerator struct {
defaultLockPrefix string
}

// NewOwnerIdGenerator 创建一个OwnerID生成器
func NewOwnerIdGenerator() *OwnerIdGenerator {
prefix := generateMachineDefaultLockIdPrefix()
// 不能太长,不然存储和索引啥的费事
Expand All @@ -28,8 +31,8 @@ func NewOwnerIdGenerator() *OwnerIdGenerator {
}
}

// 这个方法应该具有幂等性,同一个goroutine应该恒返回同一个ID
func (x *OwnerIdGenerator) getDefaultOwnId() string {
// GenOwnerId 这个方法应该具有幂等性,同一个goroutine应该恒返回同一个ID
func (x *OwnerIdGenerator) GenOwnerId() string {
// 这里为了可读性并没有将区分度最高的UUID放在前面,这是假设使用此分布式锁的各个竞争者的Hostname基本都不会相同
// 因为是同一台机器上使用分布式锁不是很有意义
return fmt.Sprintf("%s-%s-%s", x.defaultLockPrefix, goroutine_id.GetGoroutineIDAsString(), utils.RandomID())
Expand All @@ -42,16 +45,17 @@ func generateMachineDefaultLockIdPrefix() string {
return ""
}

macAddresses := strings.Builder{}
parts := make([]string, 0)
parts = append(parts, "storage-lock-owner-id")

// 主机名
hostname, _ := os.Hostname()
if hostname != "" {
macAddresses.WriteString(hostname)
macAddresses.WriteString("-")
parts = append(parts, hostname)
}

// MAC地址
macAddresses := strings.Builder{}
for index, netInterface := range netInterfaces {
macAddr := netInterface.HardwareAddr.String()
if len(macAddr) == 0 {
Expand All @@ -62,7 +66,10 @@ func generateMachineDefaultLockIdPrefix() string {
macAddresses.WriteString(",")
}
}
macAddresses.WriteString("-")
h := md5.New()
h.Write([]byte(macAddresses.String()))
macMd5 := hex.EncodeToString(h.Sum(nil))
parts = append(parts, macMd5)

return macAddresses.String()
return strings.Join(parts, "-")
}
23 changes: 23 additions & 0 deletions owner_id_generator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package storage_lock

import (
"github.com/stretchr/testify/assert"
"testing"
)

func TestOwnerIdGenerator_GenOwnerID(t *testing.T) {
generator := NewOwnerIdGenerator()

ownerIdSet := make(map[string]struct{}, 0)
for i := 0; i < 1000; i++ {

ownerId := generator.GenOwnerId()

_, exists := ownerIdSet[ownerId]
assert.False(t, exists)
ownerIdSet[ownerId] = struct{}{}

assert.NotEmpty(t, ownerId)
t.Log(ownerId)
}
}

0 comments on commit cf266da

Please sign in to comment.