Skip to content

Instantly share code, notes, and snippets.

@murDDock
Created July 19, 2022 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save murDDock/a89734f2378bf433d18c9f6a814e7918 to your computer and use it in GitHub Desktop.
Save murDDock/a89734f2378bf433d18c9f6a814e7918 to your computer and use it in GitHub Desktop.
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