Created
July 19, 2022 10:45
-
-
Save murDDock/a89734f2378bf433d18c9f6a814e7918 to your computer and use it in GitHub Desktop.
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
package main | |
import ( | |
"context" | |
"fmt" | |
"time" | |
) | |
type JudgeFunc func(interface{}) bool | |
type JudgeHelper struct { | |
Func JudgeFunc | |
ResultChan chan bool | |
ExitChan chan struct{} | |
} | |
// 封装单个判断方法 | |
// 将结果塞进 resultChan | |
// 需根据上层 exitChan 判断超时 | |
func (j *JudgeHelper) Judge(data interface{}) { | |
res := j.Func(data) | |
select { | |
case <-j.ExitChan: // 上游退出 | |
fmt.Println("exit called") | |
case j.ResultChan <- res: // 正常塞入结果 | |
} | |
} | |
type MultiJudger struct { | |
resultChan chan bool | |
exitChan chan struct{} | |
judgeFuncs []JudgeFunc | |
} | |
// 封装多个判断方法,统一管理超时以及结果 | |
// 判断方式为 func1||func2||func3 | |
func NewMultiJudger(funcs []JudgeFunc) *MultiJudger { | |
return &MultiJudger{ | |
judgeFuncs: funcs, | |
exitChan: make(chan struct{}), | |
resultChan: make(chan bool), | |
} | |
} | |
func (m *MultiJudger) MultiJudge(ctx context.Context, value interface{}) bool { | |
for _, f := range m.judgeFuncs { | |
model := &JudgeHelper{ | |
Func: f, | |
ResultChan: m.resultChan, | |
ExitChan: m.exitChan, | |
} | |
go func() { | |
model.Judge(value) | |
}() | |
} | |
return m.loopCheck(ctx) | |
} | |
func (m *MultiJudger) loopCheck(ctx context.Context) bool { | |
defer func() { | |
close(m.exitChan) | |
}() | |
count := 0 | |
for { | |
select { | |
case result := <-m.resultChan: | |
count++ | |
if result { | |
return true | |
} else { | |
// 计算判断的次数,如果已全部判断完,则返回 false | |
if count == len(m.judgeFuncs) { | |
return false | |
} | |
} | |
case <-ctx.Done(): | |
return false | |
} | |
} | |
} | |
func main() { | |
result := NewMultiJudger([]JudgeFunc{ | |
func(a any) bool { | |
fmt.Println("judge 1 called") | |
return a.(int) == 1 | |
}, | |
func(a any) bool { | |
fmt.Println("judge 2 called") | |
return a.(int) == 2 | |
}, | |
func(a any) bool { | |
time.Sleep(time.Hour) | |
fmt.Println("judge 3 called") | |
return a.(int) == 3 | |
}, | |
func(a any) bool { | |
fmt.Println("judge 4 called") | |
return a.(int) == 4 | |
}, | |
}).MultiJudge(context.Background(), 4) | |
fmt.Println("multiJudge result", result) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment