add parallelism [pre] section run before all other | update readme accordingly

This commit is contained in:
Adrien Marquès 2018-11-14 11:34:27 +01:00
parent 5fd41cae67
commit a6207e0a34
2 changed files with 57 additions and 22 deletions

View File

@ -235,17 +235,13 @@ $ nix-amer -p apt-get myserver.build
_myserver.build_ _myserver.build_
``` ```
[ comment starts with opening brackets '[' # [pre] is executed before launching everything else
[pre]
[aliases] install nginx ssh sslh
alias sshd /etc/ssh/sshd_config
alias nginx /etc/nginx/nginx.conf alias nginx /etc/nginx/nginx.conf
alias sshd /etc/ssh/sshd_config
alias sslh /etc/default/sslh alias sslh /etc/default/sslh
[install packages]
install nginx ssh
install sslh
[nginx] [nginx]
set nginx@http.gzip off set nginx@http.gzip off
service enable nginx service enable nginx

View File

@ -9,6 +9,7 @@ import (
"io" "io"
"regexp" "regexp"
"strings" "strings"
"sync"
"time" "time"
) )
@ -125,10 +126,18 @@ func (r *Reader) Execute() error {
// return fmt.Errorf("cannot upgrade | %s", err) // return fmt.Errorf("cannot upgrade | %s", err)
// } // }
refresh := make(chan bool, 1) refresh := make(chan bool, 1)
wg := new(sync.WaitGroup)
wgstatus := new(sync.WaitGroup)
// 1. create status table // 1. create status table + extract [pre] section if one
table := make([]tableSection, 0) table := make([]tableSection, 0)
index := make(map[string]int, 0)
var pre *[]instruction.T = nil
var preTable *tableSection = nil
for secname, sec := range r.Content { for secname, sec := range r.Content {
tableSec := tableSection{ tableSec := tableSection{
name: secname, name: secname,
instructions: make([]execStatus, len(*sec), len(*sec)+1), instructions: make([]execStatus, len(*sec), len(*sec)+1),
@ -137,39 +146,69 @@ func (r *Reader) Execute() error {
// for each instruction // for each instruction
for i, inst := range *sec { for i, inst := range *sec {
tableSec.instructions[i].name = inst.Raw() tableSec.instructions[i].name = inst.Raw()
tableSec.instructions[i].start = time.Now()
} }
table = append(table, tableSec) table = append(table, tableSec)
go execSection(sec, *r.Context, refresh, &table[len(table)-1]) index[secname] = len(table) - 1
// [pre] section
if secname == "pre" {
pre = sec
preTable = &tableSec
}
// add one section
wg.Add(len(*sec))
} }
// 2. create status updater // 2. launch status updater
go status(refresh, table) wgstatus.Add(1)
time.Sleep(time.Second * 10) go status(table, refresh, wgstatus)
// 3. launch [pre] (it set)
if pre != nil {
execSection(pre, *r.Context, preTable, refresh, wg)
time.Sleep(time.Second * 2)
}
// 4. launch each other section
for secname, sec := range r.Content {
// do not launch pre again
if secname == "pre" {
continue
}
i, ok := index[secname]
if !ok {
continue
}
go execSection(sec, *r.Context, &table[i], refresh, wg)
}
wg.Wait()
close(refresh) close(refresh)
wgstatus.Wait()
return nil return nil
} }
func execSection(section *[]instruction.T, ctx instruction.ExecutionContext, refresher chan<- bool, tsec *tableSection) { func execSection(section *[]instruction.T, ctx instruction.ExecutionContext, tsec *tableSection, refresher chan<- bool, wg *sync.WaitGroup) {
for i, inst := range *section { for i, inst := range *section {
tsec.instructions[i].start = time.Now()
_, err := inst.Exec(ctx) _, err := inst.Exec(ctx)
tsec.instructions[i].stop = time.Now() tsec.instructions[i].stop = time.Now()
tsec.instructions[i].stopped = true tsec.instructions[i].stopped = true
tsec.instructions[i].err = err tsec.instructions[i].err = err
refresher <- true refresher <- true
wg.Done()
} }
} }
func status(refresher chan bool, table []tableSection) { func status(table []tableSection, refresher <-chan bool, wg *sync.WaitGroup) {
fmt.Printf("status\n")
remain := false
for <-refresher { for opened := true; true; _, opened = <-refresher {
// 1. clean screen // 1. clean screen
fmt.Printf("\033[H\033[2J") fmt.Printf("\033[H\033[2J")
@ -185,7 +224,6 @@ func status(refresher chan bool, table []tableSection) {
if !inst.stopped { if !inst.stopped {
clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.name))) clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.name)))
fmt.Printf("%s\n", clifmt.Color(33, "processing")) fmt.Printf("%s\n", clifmt.Color(33, "processing"))
remain = true
continue continue
} }
@ -201,11 +239,12 @@ func status(refresher chan bool, table []tableSection) {
} }
} }
// 4. close refresher if no remaining task if !opened {
if !remain {
break break
} }
} }
wg.Done()
} }