我正在尝试使用扇出/扇入设计构建一个系统来调用多个rest API。
我的粉丝会收到一个用户列表。 Foreach用户,执行另一次扇出以创建多个http get然后聚合该用户中的数据。
这是我的粉丝方法。
< - chan struct {} 中的是我的用户信息频道
f func(struct {})struct {} 是将用户作为参数,调出我的粉丝的其他实例,合并用户数据然后返回的方法聚合用户
< - chan struct {} 是带有结果的新频道
func split(in <- chan struct{}, f func(struct{}) struct{}) <- chan struct{} {
out := make(chan struct{})
go func() {
for data := range in {
out <- f(data)
}
close(out)
}()
return out
}
合并方法用于获取多个通道并将它们合并到单个通道
func merge(in ...<- chan struct{}) <- chan struct{} {
out := make(chan struct{})
var wg sync.WaitGroup
output := func(channel <- chan struct{}) () {
for data := range channel {
out <- data
}
wg.Done()
}
for _, channel := range in {
go output(channel)
}
go func() {
wg.Wait()
close(out)
}()
wg.Add(len(in))
return out
}
用于创建扇出/扇入系统的处理方法
func Process(dataSlice []struct{}, f func(struct{}) struct{}) <-chan struct{} {
in := groupData(dataSlice) // this method is simply taking a slice of struct and returning a channel of struct with the values inside
out1 := split(in, f)
out2 := split(in, f)
out3 := split(in, f)
return merge(out1, out2, out3)
}
最后调用这个东西的方法
type Request struct {
Name string
}
type Response struct {
Name string
Age int
}
func main() {
users := make([]Request, 0)
users = append(users, Request{Name: "A"})
users = append(users, Request{Name: "B"})
users = append(users, Request{Name: "C"})
users = append(users, Request{Name: "D"})
for data := range parallel.Process(users, apply) {
fmt.Println(data)
}
}
func apply(request Request) Response {
return Response{request.Name, 1}
}
所以我的apply方法在这里很小。实际上我再次调用处理方法将我的休息api调用分成多个通道并检索该请求的所有信息。我的响应结构将取决于所谓的api。
我收到以下错误。
所以基本上我不能创建一个接受任何结构或某种请求接口的方法。
谢谢:)
更新
使用interface {}和反射lib我设法使这段代码正常工作。
func apply(request interface{}) interface{} {
if(reflect.TypeOf(request).Name() != reflect.TypeOf(Request{}).Name()) {
panic("invalid request type")
}
value := reflect.ValueOf(request)
typedRequest := value.Interface().(Request)
return Response{Name: typedRequest.Name, Age: rand.Intn(100)}
}
这感觉不对。
由于没有泛型类型,我们是否应该为我们想要使用的每种类型多次重复实现相同的方法? 建议的方法以适当的方式解决什么?