From d032458875bb5a053e41f2cb90c92dfd085ac901 Mon Sep 17 00:00:00 2001 From: GrosQuildu Date: Wed, 10 Apr 2024 15:52:30 +0200 Subject: [PATCH] improve performance --- go/hanging-goroutine.go | 49 ++++++++++++++++++++++++++++++++++++--- go/hanging-goroutine.yaml | 16 ++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/go/hanging-goroutine.go b/go/hanging-goroutine.go index 58b4d24..16533d3 100644 --- a/go/hanging-goroutine.go +++ b/go/hanging-goroutine.go @@ -11,9 +11,9 @@ var ( ) func main() { - req3(1) - fmt.Println(result) - fmt.Println(runtime.NumGoroutine()) + req5_FP(1) + fmt.Println("Result: ", result) + fmt.Println("Goroutines (must be 1 for FPs):", runtime.NumGoroutine()) } func req1(timeout time.Duration) string { @@ -110,6 +110,49 @@ func req3_FP(timeout time.Duration) { fmt.Println("finished req3") } +func req4_FP(timeout time.Duration) string { + ch := make(chan string) + // ok: hanging-goroutine + go func() { + newData := test() + ch <- newData // block + }() + select { + case result = <- ch: + fmt.Println("case result") + return result + case <- time.After(timeout): + result = <- ch + fmt.Println("case time.Afer") + return "" + } +} + +func req5_FP(timeout time.Duration) { + ch := make(chan string) + tick := time.Tick(100 * time.Millisecond) + quit := time.After(2 * time.Second) + // ok: hanging-goroutine + go func() { + newData := test() + ch <- newData // block + }() + for { + select { + case <-tick: + fmt.Print("|") + case <-quit: + result = <- ch + fmt.Println("\nquit") + return + default: + fmt.Print(".") + time.Sleep(50 * time.Millisecond) + } + } +} + + func test() string { time.Sleep(time.Second * 2) return "very important data" diff --git a/go/hanging-goroutine.yaml b/go/hanging-goroutine.yaml index d3c9c02..2517bdf 100644 --- a/go/hanging-goroutine.yaml +++ b/go/hanging-goroutine.yaml @@ -123,15 +123,29 @@ rules: - pattern-not-inside: | $CHANNEL := make(..., $T) ... + + # heuristics to limit FPs, we may miss some leaks because of these - pattern-not: | + go func(...){ + ... + $CHANNEL <- $X + ... + }(...) + ... select { case ... case ...: ... - ... =<- $CHANNEL + ... = <- $CHANNEL ... } - pattern-not: | + go func(...){ + ... + $CHANNEL <- $X + ... + }(...) + ... select { case ... case ...: