これでよしであってくれーーー〜ーーーーーーーーーー!!!!!!!!

要件

どうすん

コード

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	wg := sync.WaitGroup{}
	mu := sync.RWMutex{}

	processing := 0
	before := 0

	queue := []interface{}{}

	go func() {
		for {
			fmt.Println(time.Now().Format(time.RFC3339), "processing", processing-before)
			before = processing
			time.Sleep(time.Second)
		}
	}()

	process := func(wg *sync.WaitGroup, l sync.Locker) {
    // ここが実際のリクエストを処理するところ
		l.Lock() // リソースのロックを行って 1 つずつ処理するようにする
		defer l.Unlock()
		defer wg.Done()

		time.Sleep(100 * time.Millisecond) // 1 処理辺り 100 ms なら最大でも 1 sec 10 になるやろうという雑な ...

		var item interface{}
		item, queue = queue[0], queue[1:]

    // 実際にここで item.(type) で request を分けて request を投げる

		processing++

		fmt.Println("\\tprocessing", processing, item)
	}

	adder := func(name string) {
		defer wg.Done()

		count := 100
		for {
      // ここは実際にプロキシがリクエストを投げる直前のところみたいなイメージ
			wg.Add(1)

      // queue に足す item は本来であればリクエスト情報を含む何かしらにする(順序担保確認のため count と name を含ませてる
			queue = append(queue, fmt.Sprintf("%s_%d", name, count))

			go process(&wg, &mu) // こういう感じでリクエストをゴルーチンで生成する
			count--
			if count == 0 {
				break
			}
		}
	}

  // 複数箇所から叩かれるみたいな想定
	wg.Add(1)
	go adder("hoge") 

	wg.Add(1)
	go adder("foo")

	wg.Add(1)
	go adder("bar")

	wg.Wait()
	fmt.Println("Done")
}

動作確認

2020-07-15T18:23:14+09:00 processing 10
        processing 30 hoge_79
        processing 31 bar_91
        processing 32 hoge_78
        processing 33 bar_90
        processing 34 bar_89
        processing 35 bar_88
        processing 36 bar_87
        processing 37 bar_86
        processing 38 bar_85
2020-07-15T18:23:15+09:00 processing 9
        processing 39 bar_84
        processing 40 hoge_75
        processing 41 hoge_74
        processing 42 hoge_73
        processing 43 hoge_72
        processing 44 hoge_71
        processing 45 hoge_70
        processing 46 hoge_69
        processing 47 hoge_68
        processing 48 foo_99
2020-07-15T18:23:16+09:00 processing 10
        processing 49 foo_98
        processing 50 foo_97

動作確認してみると, foo, bar, hoge それぞれ別に投げてるリクエスト群が順番に秒間最大 10 程度処理されてるので一応要件にはそってるはず ......

なんか絶対もっと良い感じにするのはありそうなんだよな