Last active
January 25, 2021 06:51
-
-
Save andrey1s/e195269dde3fe69e6b4414dc9eaff439 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "bufio" | |
| "flag" | |
| "fmt" | |
| "log" | |
| "os" | |
| "os/exec" | |
| "strings" | |
| "sync" | |
| "time" | |
| ) | |
| var ( | |
| rate = flag.Int("rate", 1, "максимальное кол-во запусков команды в секунду") | |
| inflight = flag.Int("inflight", 1, "максимальное кол-во параллельно запущенных команд") | |
| ) | |
| func main() { | |
| start := time.Now() | |
| flag.Parse() | |
| args := flag.Args() | |
| if len(args) < 1 || *rate < 1 || *inflight < 1 { | |
| flag.Usage() | |
| return | |
| } | |
| cmd, err := exec.LookPath(args[0]) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| var argv string | |
| if len(args) > 1 { | |
| argv = strings.Join(args[1:], " ") | |
| } | |
| inp := make(chan struct{}, *inflight) | |
| ticker := time.NewTicker(time.Second) | |
| defer ticker.Stop() | |
| wg := sync.WaitGroup{} | |
| scanner := bufio.NewScanner(os.Stdin) | |
| if !scanner.Scan() { | |
| log.Fatal("failed get input data") | |
| } | |
| Scan: | |
| for { | |
| for i := 0; i < *rate; i++ { | |
| fmt.Println(time.Now().Sub(start)) | |
| inp <- struct{}{} | |
| wg.Add(1) | |
| go func(arg string) { | |
| defer wg.Done() | |
| cmd := exec.Command(cmd, strings.ReplaceAll(argv, "{}", strings.TrimSpace(arg))) | |
| cmd.Stdout = os.Stdout | |
| cmd.Stderr = os.Stderr | |
| err := cmd.Run() | |
| <-inp | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| }(scanner.Text()) | |
| if !scanner.Scan() { | |
| break Scan | |
| } | |
| } | |
| <-ticker.C | |
| } | |
| wg.Wait() | |
| fmt.Println(time.Now().Sub(start)) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Rate-limit для командной строки. | |
| Нужно написать утилиту, аналогичную xargs с ограничениями скорости запуска и количества параллельно запущенных команд. | |
| На каждую строчку stdin утилита запускает команду указанную в command-line аргументах. Команды запускаются не чаще, чем указано в аргументе "rate". Утилита должна уметь запускать несколько команд параллельно. В каждый момент времени должно быть запущено не более, чем указано в аргументе "inflight", команд. | |
| Usage: ratelimit --rate <N> --inflight <P> <command...> | |
| --rate: максимальное кол-во запусков команды в секунду | |
| --inflight: максимальное кол-во параллельно запущенных команд | |
| <command...>: команда для запуска, {} в команде заменяется на строчку из stdin. | |
| Например (в bash): | |
| $ for i in {1..60} ; do echo $i ; done | ./ratelimit --rate 15 --inflight 1 echo {} | |
| Эта команда должна отработать за ~4с. | |
| $ (echo 1 ; sleep 3 ; echo 2 ; echo 3) | ./ratelimit --rate 1 --inflight 2 echo {} | |
| Эта команда должна отработать за ~4с. | |
| Предполагается, что будет использована только стандартная библиотека. Т.е. нужна только утилита и не ожидается, что дело дойдет до тестов, reusable-компонент, каких-то других фичей и тп. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment