2017-11-15 7 views
0

イベントキューといくつかのゴルーチンがあり、無限ループ内の対応するキューからイベントを取得し、処理し、結果をチャネルに送信します。異なるキューでは同じイベントが発生する可能性があります。そのため、各イベントが1回だけチャネルに送信されるようにする必要があります。また、別のキューのメッセージが無視されます。それは建築的な問題だと私は信じていますが、これを適切に処理する方法を理解することはできません。ゴルーチンとメッセージ重複除外

私の現在のコードの簡略版は以下の通りです。

取得し、着信イベントを処理ゴルーチンがやや次のようになります。

func (q *Queue) ProcessEvents(handler Handler) { 
    lastEvent = 0 
    for { 
     events = getEvents(lastEvent) 
     for _, e := range events { 
      if e.ID > lastEvent { 
       lastEvent = event.ID 
      } 
      handler.Handle(e) 
     } 
    } 
} 

ハンドラ:

type Handler struct { 
    c chan Event 
} 

func (h *Handler) Handle(event *Event) { 
    //event processing omitted 
    h.c <- event //Now it just sends a processed event into the channel no matter what. 
} 

そしてメインで()私は

func main() { 
    msgc := make(chan Event) 
    for _, q := range queues { 
     go func(queue Queue) { 
      queue.ProcessEvents(&Handler{msgc}) 
     } 
    } 
} 
+0

チャンネルの受信側でこれを行い、同じイベントを複数回処理したくないようです。 –

+0

しかし、atmルーチンがお互いを知りませんので、イベントがすでに別のgoroutineによって処理されているかどうかを確認するにはどうすればよいですか?それが本当に主な質問です。 –

+5

シングルスレッドの場合はどうしますか?これはゴルーチンに関するものではありません。重複排除を行う場合は、メッセージが重複しているかどうかを知る必要があります。つまり、あなたが今までに受け取ったすべてのメッセージを(潜在的に)保存し、新しいメッセージをすべて古いメッセージと比較して、以前に見たことがあるかどうかを確認することを意味します。 – Adrian

答えて

0

ですから、あなたを表しています現在のアーキテクチャは次のとおりです。

Current architecture

このタイプのソリューションでは、イベントがすでに発生したかどうかを確認するためにジェネレータは共有リソースをチェックする必要があります。これは、次のようになります。これも競合なし最良のシナリオでクリティカルセクションで行われている作業の少量を考慮偉大なオーバーヘッドまででロック/アンロックを必要とし、

var hasEmmited map[string]bool 
var lock sync.Mutex 

func HasEmitted(event e) bool { 
    lock.Lock() 
    defer lock.Unlock() 
    e,ok := hasEmmited[e.ID] 
    return e && ok 
} 

func SetEmmited(event e) { 
    lock.Lock() 
    defer lock.Lock() 
    hasEmmited[e.ID] = true 
} 

2番目の図のようにアーキテクチャが少し変更されても、1つのゴールーチンでロックをかけずにフィルタリングを実行することは可能です。

A potential solution

いくつかのコメンターがgo-ルーチンを使用してソリューションを設計すると、シングルスレッドアプリケーションのための設計と同じであると述べています。私はこれが事実だとは思わない。 私は見てお勧めします:

Golang関連メッセージング:デザインパターンを扱うhttps://blog.golang.org/pipelines

いくつかのメッセージ:http://www.enterpriseintegrationpatterns.com/

エンタープライズ統合パターンは、ここで場違いに見えるかもしれませんが、それはメッセージパッシングの多くをカバー碁でも適用されるパターン。