github.com/code-to-go/safepool.lib@v0.0.0-20221205180519-ee25e63c226e/transport/lock.go (about) 1 package transport 2 3 import ( 4 "time" 5 6 "github.com/code-to-go/safepool.lib/core" 7 8 "github.com/godruoyi/go-snowflake" 9 ) 10 11 type lockFileContent struct { 12 Id uint64 13 Span time.Duration 14 } 15 16 func waitLock(e Exchanger, name string) { 17 var c lockFileContent 18 var err error 19 var id uint64 20 var shot time.Time 21 22 for shot.IsZero() && time.Since(shot) > c.Span { 23 id = c.Id 24 err = ReadJSON(e, name, &c, nil) 25 if err != nil { 26 return 27 } 28 if c.Id != id { 29 shot = time.Now() 30 } 31 time.Sleep(time.Second) 32 } 33 } 34 35 func LockFile(e Exchanger, name string, span time.Duration) (uint64, error) { 36 var c lockFileContent 37 id := snowflake.ID() 38 for c.Id != id { 39 waitLock(e, name) 40 41 err := WriteJSON(e, name, lockFileContent{ 42 Id: id, 43 Span: span, 44 }, nil) 45 if core.IsErr(err, "cannot write lock file %s: %v", name) { 46 return 0, err 47 } 48 time.Sleep(time.Second) 49 err = ReadJSON(e, name, &c, nil) 50 if core.IsErr(err, "cannot read lock file %s: %v", name) { 51 return 0, err 52 } 53 } 54 return id, nil 55 } 56 57 func UnlockFile(e Exchanger, name string, id uint64) { 58 var c lockFileContent 59 _ = ReadJSON(e, name, &c, nil) 60 if c.Id == id { 61 e.Delete(name) 62 } 63 }