4
votes

I would like to implement the following:

  • Multiple worker goroutines running, each executing some business logic.
  • Different Http handlers distributes work to these workers.
  • Input (via a channel) to each goroutine will be some data (State) which will have one Key in it.
  • Multiple data with same key is also possible.

Our requirement is that processing for a specific Key has to be serialised. e.g. goroutine 1 is processing data related to Key:1234 then other goroutines should not process other data for the same key before goroutine 1 does its job.

Can anybody suggest best approach to do that?

1
What have you tried so far? Do you already have something? - ifnotak
Just make a map[Key]chan State. - Peter
The pattern you're trying to implement is called fan-out (usually coupled with fan-in). I suggest searching for this. There are different specific ways to implement it with goroutines. There is no single "right answer". - Flimzy
a possible solution, give lock for every key, map[key]sync.Mutex - nail fei

1 Answers

1
votes

I am using map[Key]chan State Map to store mapping for Key to Channel.Creating Go Routine for each Key.

var keymap sync.Map
func handle_webservice(req WebReq) {
    val, ok := keymap.Load(req.Key)
    if ok {
        val1, _ := val.(chan Event)
        val1 <- Event{Data: req}
    } else {
        ch := make(chan Event, 5)
        go Worker(ch)
        keymap.Store(req.Key, ch)
        ch <- Event{Source: WEBSERVICE, Data: req}
    }

func sendToWorker(event Event) {
    val, ok := keymap.Load(event.Key)
    if ok {
        val1, _ := val.(chan Event)
        select {
        case val1 <- event:
        default:

        }
    } 
}