Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 为事件处理程序的多个实例创建包装器_Go_Wrapper_Channel_Knative - Fatal编程技术网

Go 为事件处理程序的多个实例创建包装器

Go 为事件处理程序的多个实例创建包装器,go,wrapper,channel,knative,Go,Wrapper,Channel,Knative,我正试图解决一个有关频道使用和正确处理这些频道的问题(很可能是设计问题)。 我正在使用Knative事件/云事件来创建和处理事件管道 我希望能够处理不同的通道,以便接收来自不同来源/方法的事件 为了做到这一点,我有下面的实现(代码已被删除,以便简洁地详细说明问题) 我有一个file1.go,它定义了一个EventHandler结构、关联的方法和两个导出的方法(CreatePreview()和SaveAndPublish()),这是应用程序的“正常”行为,实际接收/处理频道上的任何值: type

我正试图解决一个有关频道使用和正确处理这些频道的问题(很可能是设计问题)。 我正在使用Knative事件/云事件来创建和处理事件管道

我希望能够处理不同的通道,以便接收来自不同来源/方法的事件

为了做到这一点,我有下面的实现(代码已被删除,以便简洁地详细说明问题)

我有一个
file1.go
,它定义了一个
EventHandler
结构、关联的方法和两个导出的方法(
CreatePreview()
SaveAndPublish()
),这是应用程序的“正常”行为,实际接收/处理频道上的任何值:

type EventHandler struct {
  Channel chan string
}

func (ev *EventHandler) Handle(event cloudevents.Event) {
  if event.Data == nil {
    (...)
  }

  var data string
  if err := event.DataAs(&data); err != nil {
    (...)
  }

  ev.Channel <- data

  defer close(ev.Channel)
}

func (ev *EventHandler) Create(param *Element) (error) {
  (...) //Unimportant code
}

func (repo *Repository) CreatePreview(param1 string, param2 string, eventHandler *EventHandler) (*pb.PreviewResponse, error) {
  (...)
  err := eventHandler.Create(&document)
  (...)
  preview := <- eventHandler.Channel
  (...)
}

func (repo *Repository) SaveAndPublish(param1 string, param2 bool, eventHandler *EventHandler) (*pb.PublishResponse, error) {

  (...)
  err := eventHandler.Create(&documentToUpdate)
  (...)

  published := <- eventHandler.Channel
  (...)
  return repo.SomeOtherMethod(published.ID)
}
现在,我知道,为了使用
c.StartReceiver()上的
eventHandler.Handle
方法
main.go上的
c.StartReceiver()
,我不必实例化单个全局
eventHandler
,我可以定义一个可能包含事件处理程序列表的包装器(
HandlerWrapper())
main.go上的方法

但是,我不知道如何识别
EventHandler
的哪个实例,以及如何正确处理和路由这些操作,这就是我的问题:

在这种情况下,我想创建一个包装器(一个传递到
c.StartReceive()
)中的单个函数),然后让它由
Handle()的正确实例处理,该如何处理


我希望问题是清楚的。我已经想了好几天了,不知道该怎么做。

大概,您应该能够通过使用来自该事件的不同来源/方法来区分事件。例如,快速查看可以根据源划分为多个频道的节目

我看到这里没有使用的主要内容是上下文对象。你似乎可以从这个背景中找到来源。这可以在他们的示例中看到(查看receive函数)

例如:

// these are all the handlers for the different sources.
type EventHandlers map[string]CloudEventHandler

var _eventHandlerKey = "cloudEventHandlers"

func HandlerWrapper(ctx context.Context, event cloudevents.Event) {
    // Get event source from event context.
    src := event.Context.Source
    // Then get the appropriate handler for that source (attached to context).
    handler := ctx.Value(_eventHandlers).(Values)[src]
    // ex: src = "/foo" 
    handler.SendToChannel(event)
}

func main() {
    eventHandlers := make(map[string]CloudEventHandler)
    // create all the channels we need, add it to the context.
    for _, source := range sourceTypes { // foo bar baz
        handler := NewHandler(source)
        eventHandlers[source] = handler
    }

  // start HTTP server
  go func() {
    // Add the handlers to the context.
    context := context.WithValue(context.Background(), _eventHandlerKey, eventHandlers)
    log.Fatal(c.StartReceiver(context.Background(), HandlerWrapper))
  }
}()

如果有3个不同的源需要支持,您可以使用来实例化这些不同的通道和所有这些实现的接口

// CloudEventHandler Handles sending cloud events to the proper channel for processing.
type CloudEventHandler interface {
    SendToChannel(cloudEvents.Event)
}

type fooHandler struct {channel chan string}
type barHandler struct {channel chan int}
type bazHandler struct {channel chan bool}

func NewHandler(source string) CloudEventHandler {
    switch source {
    case "/foo":
        return &fooHandler{channel: make(chan string, 2)} // buffered channel
    case "/bar":
        return &barHandler{channel: make(chan int, 2)}
    case "/baz":
        return &bazHandler{channel: make(chan bool, 2)}
    }
}

func (fh *fooHandler) SendToChannel(event CloudEvents.Event) {
    var data string
    if err := event.DataAs(&data); err != nil {
        // (...)
    }

    go func() {
        fh.channel <- data
    }()
}

func (bh *barHandler) SendToChannel(event CloudEvents.Event) {
    var data int
    if err := event.DataAs(&data); err != nil {
        // (...)
    }

    go func() {
        bh.channel <- data
    }()
}
//CloudEventHandler处理将云事件发送到适当的通道进行处理的问题。
类型CloudEventHandler接口{
SendToChannel(cloudEvents.Event)
}
类型foodhandler结构{channel chan string}
类型barHandler结构{channel chan int}
类型bazHandler结构{channel chan bool}
func NewHandler(源字符串)CloudEventHandler{
开关电源{
案例“/foo”:
return&foodhandler{channel:make(chan string,2)}//缓冲通道
案例“/bar”:
return&barHandler{channel:make(chan int,2)}
案例“/baz”:
返回和返回{通道:make(chan bool,2)}
}
}
func(fh*foodhandler)SendToChannel(event CloudEvents.event){
变量数据字符串
如果错误:=event.DataAs(&data);错误!=nil{
// (...)
}
go func(){
跳频信道
// CloudEventHandler Handles sending cloud events to the proper channel for processing.
type CloudEventHandler interface {
    SendToChannel(cloudEvents.Event)
}

type fooHandler struct {channel chan string}
type barHandler struct {channel chan int}
type bazHandler struct {channel chan bool}

func NewHandler(source string) CloudEventHandler {
    switch source {
    case "/foo":
        return &fooHandler{channel: make(chan string, 2)} // buffered channel
    case "/bar":
        return &barHandler{channel: make(chan int, 2)}
    case "/baz":
        return &bazHandler{channel: make(chan bool, 2)}
    }
}

func (fh *fooHandler) SendToChannel(event CloudEvents.Event) {
    var data string
    if err := event.DataAs(&data); err != nil {
        // (...)
    }

    go func() {
        fh.channel <- data
    }()
}

func (bh *barHandler) SendToChannel(event CloudEvents.Event) {
    var data int
    if err := event.DataAs(&data); err != nil {
        // (...)
    }

    go func() {
        bh.channel <- data
    }()
}