mirror of
https://github.com/duke-git/lancet.git
synced 2026-03-01 00:35:28 +08:00
Compare commits
2 Commits
47e82aad39
...
093f4a2286
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
093f4a2286 | ||
|
|
f7ada6093c |
@@ -3,6 +3,7 @@ package concurrency
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -199,3 +200,159 @@ func ExampleChannel_Bridge() {
|
||||
// true
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleKeyedLocker_Do() {
|
||||
locker := NewKeyedLocker[string](2 * time.Second)
|
||||
|
||||
task := func() {
|
||||
fmt.Println("Executing task...")
|
||||
time.Sleep(1 * time.Second)
|
||||
fmt.Println("Task completed.")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := locker.Do(ctx, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel2()
|
||||
|
||||
if err := locker.Do(ctx2, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
}
|
||||
|
||||
func ExampleRWKeyedLocker_Lock() {
|
||||
locker := NewRWKeyedLocker[string](2 * time.Second)
|
||||
|
||||
// Simulate a key
|
||||
key := "resource_key"
|
||||
|
||||
fn := func() {
|
||||
fmt.Println("Starting write operation...")
|
||||
// Simulate write operation, assuming it takes 2 seconds
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
fmt.Println("Write operation completed!")
|
||||
}
|
||||
|
||||
// Acquire the write lock and execute the operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Execute the lock operation with a 3-second timeout
|
||||
err := locker.Lock(ctx, key, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//output:
|
||||
//Starting write operation...
|
||||
//Write operation completed!
|
||||
}
|
||||
|
||||
func ExampleRWKeyedLocker_RLock() {
|
||||
locker := NewRWKeyedLocker[string](2 * time.Second)
|
||||
|
||||
// Simulate a key
|
||||
key := "resource_key"
|
||||
|
||||
fn := func() {
|
||||
fmt.Println("Starting write operation...")
|
||||
// Simulate write operation, assuming it takes 2 seconds
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
fmt.Println("Write operation completed!")
|
||||
}
|
||||
|
||||
// Acquire the write lock and execute the operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Execute the lock operation with a 3-second timeout
|
||||
err := locker.RLock(ctx, key, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//output:
|
||||
//Starting write operation...
|
||||
//Write operation completed!
|
||||
}
|
||||
|
||||
func ExampleTryKeyedLocker() {
|
||||
locker := NewTryKeyedLocker[string]()
|
||||
|
||||
key := "resource_key"
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
time.Sleep(1 * time.Second)
|
||||
// Unlock after work is done
|
||||
locker.Unlock(key)
|
||||
fmt.Println("Lock released")
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
//output:
|
||||
//Lock acquired
|
||||
//Lock released
|
||||
}
|
||||
|
||||
func ExampleTryKeyedLocker_TryLock() {
|
||||
locker := NewTryKeyedLocker[string]()
|
||||
|
||||
key := "resource_key"
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
if locker.TryLock(key) {
|
||||
time.Sleep(2 * time.Second)
|
||||
locker.Unlock(key)
|
||||
}
|
||||
close(done)
|
||||
}()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
locker.Unlock(key)
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
// wait for the goroutine to finish
|
||||
<-done
|
||||
|
||||
fmt.Println("Retrying...")
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
locker.Unlock(key)
|
||||
fmt.Println("Lock released")
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Lock failed
|
||||
// Retrying...
|
||||
// Lock acquired
|
||||
// Lock released
|
||||
}
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
-----BEGIN rsa private key-----
|
||||
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
|
||||
-----END rsa private key-----
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
-----BEGIN rsa public key-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoJVrCBR3dJsdj0Gg9tlk
|
||||
ToGvywJnJqVWBPgjnS+Hn5Ksxk1yzBieL0aQ84hVXYt0yhCgiDl/eDmgdawqUZ5j
|
||||
2PhFBDahjvBnchY2ViZXNE61ya3YPEPIwUsZ1Wsmzu5cX6gA1HqE2nx8iZlJQcbG
|
||||
/rdoxyebhdvUj6iGGvgskggkVYvDYuct+iRekfHMxG3ON+wJ31AC2+0B6w6vgvt1
|
||||
1uZpAnG/lR2APzTxnDHVHEXGmTticlb3ko4zRvTREsY4zSFSq0Io5K29ooYw/pHv
|
||||
hw3hvirRzjYkaxK5yzLCw788FkRLjpO4yuTYxD3pQ6HpfMMpTl9nCK3IOMqbyaX2
|
||||
espY0zmJr/vqbWgqzSlyptXDW80/mAn1nDhQe1qkTW94gqL9GKhGtydFCOKxfIM7
|
||||
Y5X7DlMXc1kbup5pw3p8xkltD4KNcG+QuePPIvFp05oiLAHZpO0d3i2pAtiVyQ+7
|
||||
YvlEQlqw0LCz8MaDRGZg4+Q3nxPtmg4z7Ms8gsZaKFiyRZCMOg6NEDFwhZPAFJ+6
|
||||
JH6Pnbq244LkKYCJNuZpp9rYeOWIIMNevQyHc6iorInnSGJfzxz347NfwV2fcn4b
|
||||
gQGPbHJOMNDlHnVZgp2ONlVvaSC6DWWE1iGNmOcNcc09PJV87qf8x9SI5FXipsvn
|
||||
fiVynueMcgSwqQRddt4O408CAwEAAQ==
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA36S1XbDH0Hv2xkxzyVRX
|
||||
ye3O4SBbSRpjq4DFfukkqBM9YDk0JjBjjyYM2678mCRrH6tgDrMBl3GnJp2dufbi
|
||||
SaCLxYlodGExlWJrY0wRwGBtQHsJE4+wfxtGcjCoGyqCgAw4/fOYSlx3ECBm/mXi
|
||||
xPNzn0inGTYQ0JtkFBxrX/fH8nKaoUoAM9PJaGJXXZNuhO8yhennfQBqTydLRCq7
|
||||
g8deK/HG+SLP3LjejQQkZGKVddC+9HdYm+YxFi7y+5hPj42PcBYiXZy9IHJLZI5U
|
||||
x1hHJNpgf3djLm73XyFqDqcmkQZip77B+y3chLpse8ocscf3uWjMouJ1fsdnEHya
|
||||
SPrqkPcrdPbzGiV4SZTLdVoEEeqJnFK6vmCKDQZ37E8CO4UxVB8L5MlQl7FIv+7X
|
||||
cYn2ped+YLX2RHGM9snBft854RRnUs/7Vy13ml3vqCgzUsRRQ/9VHMNO4t6Lqk8n
|
||||
syFfD5oO+0MsKKedFKAEfH8MeTBTgPsdd/tfZnMk8tsAkrVGVzongiVRIIN3zAJx
|
||||
/i+sLkDYm0+tHGEgcjahuErEO5xEFCLLaBmdL5ugQ9ZgqM31Nq92ZhW/TXt2EORn
|
||||
Fmd0dnP4Ssdz0JfLqW9S3orr/Mixrd2xC+V2+Diul2PTfhIMbs7AoTVy4LepSeLd
|
||||
BKlFoBdRd39a+D+S8PyCVSUCAwEAAQ==
|
||||
-----END rsa public key-----
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
## 源码:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/concurrency/channel.go](https://github.com/duke-git/lancet/blob/main/concurrency/channel.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/concurrency/keyed_locker.go](https://github.com/duke-git/lancet/blob/main/concurrency/keyed_locker.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -35,6 +36,18 @@ import (
|
||||
- [Take](#Take)
|
||||
- [Tee](#Tee)
|
||||
|
||||
### KeyedLocker
|
||||
|
||||
- [NewKeyedLocker](#NewKeyedLocker)
|
||||
- [KeyedLocker_Do](#Do)
|
||||
- [NewRWKeyedLocker](#NewRWKeyedLocker)
|
||||
- [RWKeyedLocker_RLock](#RLock)
|
||||
- [RWKeyedLocker_Lock](#Lock)
|
||||
- [NewTryKeyedLocker](#NewTryKeyedLocker)
|
||||
- [TryKeyedLocker_TryLock](#TryLock)
|
||||
- [TryKeyedLocker_Unlock](#Unlock)
|
||||
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 文档
|
||||
@@ -452,3 +465,385 @@ func main() {
|
||||
// 1
|
||||
}
|
||||
```
|
||||
|
||||
### KeyedLocker
|
||||
|
||||
### <span id="NewKeyedLocker">NewKeyedLocker</span>
|
||||
|
||||
<p>NewKeyedLocker创建一个新的KeyedLocker,并为锁的过期设置指定的 TTL。KeyedLocker 是一个简单的键值锁实现,允许非阻塞的锁获取。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func NewKeyedLocker[K comparable](ttl time.Duration) *KeyedLocker[K]
|
||||
```
|
||||
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewKeyedLocker[string](2 * time.Second)
|
||||
|
||||
task := func() {
|
||||
fmt.Println("Executing task...")
|
||||
time.Sleep(1 * time.Second)
|
||||
fmt.Println("Task completed.")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := locker.Do(ctx, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel2()
|
||||
|
||||
if err := locker.Do(ctx2, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Do">KeyedLocker_Do</span>
|
||||
|
||||
<p>为指定的键获取锁并执行提供的函数。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *KeyedLocker[K]) Do(ctx context.Context, key K, fn func()) error
|
||||
```
|
||||
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewKeyedLocker[string](2 * time.Second)
|
||||
|
||||
task := func() {
|
||||
fmt.Println("Executing task...")
|
||||
time.Sleep(1 * time.Second)
|
||||
fmt.Println("Task completed.")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := locker.Do(ctx, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel2()
|
||||
|
||||
if err := locker.Do(ctx2, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="NewRWKeyedLocker">NewRWKeyedLocker</span>
|
||||
|
||||
<p>NewRWKeyedLocker创建一个新的RWKeyedLocker,并为锁的过期设置指定的 TTL。RWKeyedLocker 是一个简单的键值读写锁实现,允许非阻塞的锁获取。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func NewRWKeyedLocker[K comparable](ttl time.Duration) *RWKeyedLocker[K]
|
||||
```
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewRWKeyedLocker[string](2 * time.Second)
|
||||
|
||||
// Simulate a key
|
||||
key := "resource_key"
|
||||
|
||||
fn := func() {
|
||||
fmt.Println("Starting write operation...")
|
||||
// Simulate write operation, assuming it takes 2 seconds
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
fmt.Println("Write operation completed!")
|
||||
}
|
||||
|
||||
// Acquire the write lock and execute the operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Execute the lock operation with a 3-second timeout
|
||||
err := locker.Lock(ctx, key, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//output:
|
||||
//Starting write operation...
|
||||
//Write operation completed!
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="RLock">RWKeyedLocker_RLock</span>
|
||||
|
||||
<p>RLock为指定的键获取读锁并执行提供的函数。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *RWKeyedLocker[K]) RLock(ctx context.Context, key K, fn func()) error
|
||||
```
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewRWKeyedLocker[string](2 * time.Second)
|
||||
|
||||
// Simulate a key
|
||||
key := "resource_key"
|
||||
|
||||
fn := func() {
|
||||
fmt.Println("Starting write operation...")
|
||||
// Simulate write operation, assuming it takes 2 seconds
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
fmt.Println("Write operation completed!")
|
||||
}
|
||||
|
||||
// Acquire the write lock and execute the operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Execute the lock operation with a 3-second timeout
|
||||
err := locker.RLock(ctx, key, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//output:
|
||||
//Starting write operation...
|
||||
//Write operation completed!
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Lock">RWKeyedLocker_Lock</span>
|
||||
|
||||
<p>RLock为指定的键获取锁并执行提供的函数。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *RWKeyedLocker[K]) Lock(ctx context.Context, key K, fn func()) error
|
||||
```
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := NewRWKeyedLocker[string](2 * time.Second)
|
||||
|
||||
// Simulate a key
|
||||
key := "resource_key"
|
||||
|
||||
fn := func() {
|
||||
fmt.Println("Starting write operation...")
|
||||
// Simulate write operation, assuming it takes 2 seconds
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
fmt.Println("Write operation completed!")
|
||||
}
|
||||
|
||||
// Acquire the write lock and execute the operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Execute the lock operation with a 3-second timeout
|
||||
err := locker.Lock(ctx, key, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//output:
|
||||
//Starting write operation...
|
||||
//Write operation completed!
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="NewTryKeyedLocker">NewTryKeyedLocker</span>
|
||||
|
||||
<p>创建一个TryKeyedLocker实例,TryKeyedLocker是KeyedLocker的非阻塞版本。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func NewTryKeyedLocker[K comparable]() *TryKeyedLocker[K]
|
||||
```
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewTryKeyedLocker[string]()
|
||||
|
||||
key := "resource_key"
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
time.Sleep(1 * time.Second)
|
||||
// Unlock after work is done
|
||||
locker.Unlock(key)
|
||||
fmt.Println("Lock released")
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
//output:
|
||||
//Lock acquired
|
||||
//Lock released
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="TryLock">TryKeyedLocker_TryLock</span>
|
||||
|
||||
<p>TryLock尝试获取指定键的锁。如果锁成功获取,则返回true,否则返回false。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *TryKeyedLocker[K]) TryLock(key K) bool
|
||||
```
|
||||
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewTryKeyedLocker[string]()
|
||||
|
||||
key := "resource_key"
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
time.Sleep(1 * time.Second)
|
||||
// Unlock after work is done
|
||||
locker.Unlock(key)
|
||||
fmt.Println("Lock released")
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
//output:
|
||||
//Lock acquired
|
||||
//Lock released
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Unlock">TryKeyedLocker_Unlock</span>
|
||||
|
||||
<p>释放指定键的锁。</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *TryKeyedLocker[K]) Unlock(key K)
|
||||
```
|
||||
|
||||
<b>示例:<span style="float:right;display:inline-block;">[运行](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewTryKeyedLocker[string]()
|
||||
|
||||
key := "resource_key"
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
time.Sleep(1 * time.Second)
|
||||
// Unlock after work is done
|
||||
locker.Unlock(key)
|
||||
fmt.Println("Lock released")
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
//output:
|
||||
//Lock acquired
|
||||
//Lock released
|
||||
}
|
||||
```
|
||||
@@ -6,6 +6,7 @@ Package concurrency contain some functions to support concurrent programming. eg
|
||||
## Source:
|
||||
|
||||
- [https://github.com/duke-git/lancet/blob/main/concurrency/channel.go](https://github.com/duke-git/lancet/blob/main/concurrency/channel.go)
|
||||
- [https://github.com/duke-git/lancet/blob/main/concurrency/keyed_locker.go](https://github.com/duke-git/lancet/blob/main/concurrency/keyed_locker.go)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -19,7 +20,9 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
|
||||
### Channel
|
||||
|
||||
- [NewChannel](#NewChannel)
|
||||
- [Bridge](#Bridge)
|
||||
- [FanIn](#FanIn)
|
||||
@@ -31,6 +34,17 @@ import (
|
||||
- [Take](#Take)
|
||||
- [Tee](#Tee)
|
||||
|
||||
### KeyedLocker
|
||||
|
||||
- [NewKeyedLocker](#NewKeyedLocker)
|
||||
- [KeyedLocker_Do](#Do)
|
||||
- [NewRWKeyedLocker](#NewRWKeyedLocker)
|
||||
- [RWKeyedLocker_RLock](#RLock)
|
||||
- [RWKeyedLocker_Lock](#Lock)
|
||||
- [NewTryKeyedLocker](#NewTryKeyedLocker)
|
||||
- [TryKeyedLocker_TryLock](#TryLock)
|
||||
- [TryKeyedLocker_Unlock](#Unlock)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Documentation
|
||||
@@ -437,4 +451,386 @@ func main() {
|
||||
// 1
|
||||
// 1
|
||||
}
|
||||
```
|
||||
|
||||
### KeyedLocker
|
||||
|
||||
### <span id="NewKeyedLocker">NewKeyedLocker</span>
|
||||
|
||||
<p>KeyedLocker is a simple implementation of a keyed locker that allows for non-blocking lock acquisition.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func NewKeyedLocker[K comparable](ttl time.Duration) *KeyedLocker[K]
|
||||
```
|
||||
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewKeyedLocker[string](2 * time.Second)
|
||||
|
||||
task := func() {
|
||||
fmt.Println("Executing task...")
|
||||
time.Sleep(1 * time.Second)
|
||||
fmt.Println("Task completed.")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := locker.Do(ctx, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel2()
|
||||
|
||||
if err := locker.Do(ctx2, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Do">KeyedLocker_Do</span>
|
||||
|
||||
<p>Acquires a lock for the specified key and executes the provided function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *KeyedLocker[K]) Do(ctx context.Context, key K, fn func()) error
|
||||
```
|
||||
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewKeyedLocker[string](2 * time.Second)
|
||||
|
||||
task := func() {
|
||||
fmt.Println("Executing task...")
|
||||
time.Sleep(1 * time.Second)
|
||||
fmt.Println("Task completed.")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := locker.Do(ctx, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel2()
|
||||
|
||||
if err := locker.Do(ctx2, "mykey", task); err != nil {
|
||||
log.Fatalf("Error executing task: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("Task successfully executed.")
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
// Executing task...
|
||||
// Task completed.
|
||||
// Task successfully executed.
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="NewRWKeyedLocker">NewRWKeyedLocker</span>
|
||||
|
||||
<p>RWKeyedLocker is a read-write version of KeyedLocker.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func NewRWKeyedLocker[K comparable](ttl time.Duration) *RWKeyedLocker[K]
|
||||
```
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewRWKeyedLocker[string](2 * time.Second)
|
||||
|
||||
// Simulate a key
|
||||
key := "resource_key"
|
||||
|
||||
fn := func() {
|
||||
fmt.Println("Starting write operation...")
|
||||
// Simulate write operation, assuming it takes 2 seconds
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
fmt.Println("Write operation completed!")
|
||||
}
|
||||
|
||||
// Acquire the write lock and execute the operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Execute the lock operation with a 3-second timeout
|
||||
err := locker.Lock(ctx, key, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//output:
|
||||
//Starting write operation...
|
||||
//Write operation completed!
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="RLock">RWKeyedLocker_RLock</span>
|
||||
|
||||
<p>Acquires a read lock for the specified key and executes the provided function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *RWKeyedLocker[K]) RLock(ctx context.Context, key K, fn func()) error
|
||||
```
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewRWKeyedLocker[string](2 * time.Second)
|
||||
|
||||
// Simulate a key
|
||||
key := "resource_key"
|
||||
|
||||
fn := func() {
|
||||
fmt.Println("Starting write operation...")
|
||||
// Simulate write operation, assuming it takes 2 seconds
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
fmt.Println("Write operation completed!")
|
||||
}
|
||||
|
||||
// Acquire the write lock and execute the operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Execute the lock operation with a 3-second timeout
|
||||
err := locker.RLock(ctx, key, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//output:
|
||||
//Starting write operation...
|
||||
//Write operation completed!
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Lock">RWKeyedLocker_Lock</span>
|
||||
|
||||
<p>Acquires a write lock for the specified key and executes the provided function.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *RWKeyedLocker[K]) Lock(ctx context.Context, key K, fn func()) error
|
||||
```
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := NewRWKeyedLocker[string](2 * time.Second)
|
||||
|
||||
// Simulate a key
|
||||
key := "resource_key"
|
||||
|
||||
fn := func() {
|
||||
fmt.Println("Starting write operation...")
|
||||
// Simulate write operation, assuming it takes 2 seconds
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
fmt.Println("Write operation completed!")
|
||||
}
|
||||
|
||||
// Acquire the write lock and execute the operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Execute the lock operation with a 3-second timeout
|
||||
err := locker.Lock(ctx, key, fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//output:
|
||||
//Starting write operation...
|
||||
//Write operation completed!
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="NewTryKeyedLocker">NewTryKeyedLocker</span>
|
||||
|
||||
<p>TryKeyedLocker is a non-blocking version of KeyedLocker.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func NewTryKeyedLocker[K comparable]() *TryKeyedLocker[K]
|
||||
```
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewTryKeyedLocker[string]()
|
||||
|
||||
key := "resource_key"
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
time.Sleep(1 * time.Second)
|
||||
// Unlock after work is done
|
||||
locker.Unlock(key)
|
||||
fmt.Println("Lock released")
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
//output:
|
||||
//Lock acquired
|
||||
//Lock released
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="TryLock">TryKeyedLocker_TryLock</span>
|
||||
|
||||
<p>TryLock tries to acquire a lock for the specified key.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *TryKeyedLocker[K]) TryLock(key K) bool
|
||||
```
|
||||
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewTryKeyedLocker[string]()
|
||||
|
||||
key := "resource_key"
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
time.Sleep(1 * time.Second)
|
||||
// Unlock after work is done
|
||||
locker.Unlock(key)
|
||||
fmt.Println("Lock released")
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
//output:
|
||||
//Lock acquired
|
||||
//Lock released
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="Unlock">TryKeyedLocker_Unlock</span>
|
||||
|
||||
<p>Unlock releases the lock for the specified key.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *TryKeyedLocker[K]) Unlock(key K)
|
||||
```
|
||||
|
||||
<b>Example:<span style="float:right;display:inline-block;">[Run](https://go.dev/play/p/todo)</span></b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/concurrency"
|
||||
)
|
||||
|
||||
func main() {
|
||||
locker := concurrency.NewTryKeyedLocker[string]()
|
||||
|
||||
key := "resource_key"
|
||||
|
||||
if locker.TryLock(key) {
|
||||
fmt.Println("Lock acquired")
|
||||
time.Sleep(1 * time.Second)
|
||||
// Unlock after work is done
|
||||
locker.Unlock(key)
|
||||
fmt.Println("Lock released")
|
||||
} else {
|
||||
fmt.Println("Lock failed")
|
||||
}
|
||||
|
||||
//output:
|
||||
//Lock acquired
|
||||
//Lock released
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user