-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
757 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"github.com/sirupsen/logrus" | ||
"log" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
"testing" | ||
) | ||
|
||
func handleExitSignals(ctx context.Context, logger *logrus.Entry, cancel context.CancelFunc) { | ||
ch := make(chan os.Signal, 32) | ||
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) | ||
|
||
for { | ||
select { | ||
case s := <-ch: | ||
logger.WithField("signal", s).Debugf("Caught exit signal") | ||
cancel() | ||
return | ||
case <-ctx.Done(): | ||
return | ||
} | ||
} | ||
} | ||
|
||
func TestSignal(t *testing.T) { | ||
// 创建一个channel用于接收操作系统发送的信号 | ||
sigChan := make(chan os.Signal, 1) | ||
// 监听SIGINT和SIGTERM信号 | ||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) | ||
|
||
// 创建一个channel用于通知程序退出 | ||
exitChan := make(chan struct{}) | ||
|
||
// 启动一个goroutine来处理信号 | ||
go func() { | ||
select { | ||
// 阻塞等待信号 | ||
case sig := <-sigChan: | ||
// 收到信号后打印日志 | ||
log.Printf("Received signal: %v", sig) | ||
// 向exitChan发送消息,通知程序退出 | ||
close(exitChan) | ||
} | ||
}() | ||
|
||
// 在主goroutine中等待exitChan被关闭,然后退出程序 | ||
<-exitChan | ||
log.Println("Shutting down gracefully...") | ||
// 在这里执行任何需要在退出时清理的操作 | ||
log.Println("Exiting.") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"math/rand" | ||
"sync" | ||
"testing" | ||
) | ||
|
||
// 测试并发调用rand冲突的概率 | ||
func TestRand(t *testing.T) { | ||
counter := make(map[int]int) | ||
|
||
wg := sync.WaitGroup{} | ||
var mu sync.Mutex | ||
|
||
for i := 0; i < 30; i++ { | ||
wg.Add(1) | ||
go func() { | ||
defer wg.Done() | ||
for i := 0; i < 100000; i++ { | ||
randInt := rand.Int() | ||
mu.Lock() | ||
counter[randInt] = counter[randInt] + 1 | ||
mu.Unlock() | ||
} | ||
}() | ||
} | ||
wg.Wait() | ||
for k, v := range counter { | ||
if v > 1 { | ||
fmt.Println(fmt.Sprintf("k=%d, v=%d", k, v)) | ||
} | ||
} | ||
fmt.Println("end") | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"k8s.io/apimachinery/pkg/util/runtime" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestTimeFormat(t *testing.T) { | ||
// 获取当前时间 | ||
currentTime := time.Now() | ||
// 设置时区 | ||
location, _ := time.LoadLocation("Asia/Shanghai") | ||
// 将时间转换为指定时区 | ||
currentTime = currentTime.In(location) | ||
// 格式化时间为指定的字符串格式 | ||
formattedTime := currentTime.Format("2006-01-02T15:04:05-07:00") | ||
|
||
// 输出格式化后的时间字符串 | ||
fmt.Println("格式化后的时间字符串:", formattedTime) | ||
} | ||
|
||
var count = 0 | ||
|
||
func TestTicker(t *testing.T) { | ||
background := context.Background() | ||
err := PollUntilContextTimeout(background, time.Second, 20*time.Second, false, printTime()) | ||
if err != nil { | ||
fmt.Println(err) | ||
} | ||
} | ||
|
||
func printTime() ConditionWithContextFunc { | ||
return func(_ context.Context) (done bool, err error) { | ||
count++ | ||
if count > 12 { | ||
return true, nil | ||
} else { | ||
fmt.Println(time.Now()) | ||
return false, nil | ||
} | ||
} | ||
} | ||
|
||
func PollUntilContextTimeout(ctx context.Context, interval, timeout time.Duration, immediate bool, condition ConditionWithContextFunc) error { | ||
deadlineCtx, deadlineCancel := context.WithTimeout(ctx, timeout) | ||
defer deadlineCancel() | ||
return loopConditionUntilContext(deadlineCtx, interval, immediate, false, condition) | ||
} | ||
|
||
// ConditionWithContextFunc returns true if the condition is satisfied, or an error | ||
// if the loop should be aborted. | ||
// | ||
// The caller passes along a context that can be used by the condition function. | ||
type ConditionWithContextFunc func(context.Context) (done bool, err error) | ||
|
||
// 多次循环,每次循环后延迟加倍,直到超时 | ||
func loopConditionUntilContext(ctx context.Context, initialInterval time.Duration, immediate, sliding bool, condition ConditionWithContextFunc) error { | ||
t := time.NewTimer(initialInterval) | ||
interval := initialInterval | ||
ratio := time.Duration(2) | ||
defer t.Stop() | ||
|
||
var timeCh <-chan time.Time | ||
doneCh := ctx.Done() | ||
|
||
// if immediate is true the condition is | ||
// guaranteed to be executed at least once, | ||
// if we haven't requested immediate execution, delay once | ||
if immediate { | ||
if ok, err := func() (bool, error) { | ||
defer runtime.HandleCrash() | ||
return condition(ctx) | ||
}(); err != nil || ok { | ||
return err | ||
} | ||
} else { | ||
timeCh = t.C | ||
select { | ||
case <-doneCh: | ||
return ctx.Err() | ||
case <-timeCh: | ||
} | ||
} | ||
|
||
for { | ||
// checking ctx.Err() is slightly faster than checking a select | ||
if err := ctx.Err(); err != nil { | ||
return err | ||
} | ||
|
||
if !sliding { | ||
interval = interval * ratio | ||
t.Reset(interval) | ||
} | ||
if ok, err := func() (bool, error) { | ||
defer runtime.HandleCrash() | ||
return condition(ctx) | ||
}(); err != nil || ok { | ||
return err | ||
} | ||
if sliding { | ||
interval = interval * ratio | ||
t.Reset(interval) | ||
} | ||
|
||
if timeCh == nil { | ||
timeCh = t.C | ||
} | ||
|
||
// NOTE: b/c there is no priority selection in golang | ||
// it is possible for this to race, meaning we could | ||
// trigger t.C and doneCh, and t.C select falls through. | ||
// In order to mitigate we re-check doneCh at the beginning | ||
// of every loop to guarantee at-most one extra execution | ||
// of condition. | ||
select { | ||
case <-doneCh: | ||
return ctx.Err() | ||
case <-timeCh: | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package concurrent | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
"sync/atomic" | ||
"testing" | ||
) | ||
|
||
func TestAtomic(t *testing.T) { | ||
var a int64 = 0 | ||
var b int64 = 0 | ||
wg := sync.WaitGroup{} | ||
for i := 0; i < 500; i++ { | ||
wg.Add(1) | ||
go func() { | ||
defer wg.Done() | ||
atomic.AddInt64(&a, 1) | ||
}() | ||
} | ||
wg.Wait() | ||
|
||
for i := 0; i < 500; i++ { | ||
wg.Add(1) | ||
go func() { | ||
defer wg.Done() | ||
b = b + 1 | ||
}() | ||
} | ||
wg.Wait() | ||
fmt.Println("a=", a) | ||
fmt.Println("b=", b) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.