Created
June 11, 2015 18:16
-
-
Save techjanitor/052cc09f821016806dca to your computer and use it in GitHub Desktop.
concurrent exec: single producer, multiple consumer
This file contains 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" | |
"io/ioutil" | |
"os" | |
"os/exec" | |
"strings" | |
"sync" | |
) | |
func main() { | |
// Flags for output | |
commandFlag := flag.String("command", "", "what command to send to shell") | |
hostsFlag := flag.String("hosts", "", "the file with hosts") | |
conFlag := flag.Int("threads", 8, "level of concurrent operations") | |
// Parse flags | |
flag.Parse() | |
switch { | |
case *commandFlag == "": | |
fmt.Fprintln(os.Stderr, "command required") | |
os.Exit(1) | |
case *hostsFlag == "": | |
fmt.Fprintln(os.Stderr, "host file required") | |
os.Exit(1) | |
} | |
// initialize waitgroup | |
var wg sync.WaitGroup | |
// make channel for the commands | |
tasks := make(chan *exec.Cmd, 64) | |
// create buffer for output | |
out := bufio.NewWriter(os.Stdout) | |
// for loop that will make x routines set from threads flag | |
for i := 0; i < *conFlag; i++ { | |
wg.Add(1) | |
go func() { | |
// range through tasks channel | |
for cmd := range tasks { | |
// execute command and get output | |
cmdout, err := cmd.Output() | |
if err != nil { | |
fmt.Fprintln(os.Stderr, err) | |
return | |
} | |
// print to buffer | |
fmt.Fprintf(out, "%s", cmdout) | |
out.Flush() | |
} | |
wg.Done() | |
}() | |
} | |
// read file | |
file, err := ioutil.ReadFile(*hostsFlag) | |
if err != nil { | |
fmt.Fprintln(os.Stderr, "problem opening file") | |
os.Exit(1) | |
} | |
// trim last newline from file | |
h := strings.TrimSpace(string(file)) | |
// split on newlines into slice | |
hosts := strings.Split(h, "\n") | |
// range over hostnames in slice | |
for _, host := range hosts { | |
tasks <- exec.Command("mco", "shell", "--publish_timeout=2", "-t2", "-I", host, *commandFlag) | |
} | |
// close channel | |
close(tasks) | |
// wait until routines are done | |
wg.Wait() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment