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_
```
[ comment starts with opening brackets '['
[aliases]
alias sshd /etc/ssh/sshd_config
# [pre] is executed before launching everything else
[pre]
install nginx ssh sslh
alias nginx /etc/nginx/nginx.conf
alias sshd /etc/ssh/sshd_config
alias sslh /etc/default/sslh
[install packages]
install nginx ssh
install sslh
[nginx]
set nginx@http.gzip off
service enable nginx

View File

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