AppManager: Run installation in background
Separates process into two sequential tasks: commit to config repo and
monitor release resources.
Change-Id: Ib208839dffc475b5d9c5d21758bc2a18a7f76cb7
diff --git a/core/installer/tasks/install.go b/core/installer/tasks/install.go
new file mode 100644
index 0000000..8b5bef7
--- /dev/null
+++ b/core/installer/tasks/install.go
@@ -0,0 +1,52 @@
+package tasks
+
+import (
+ "github.com/giolekva/pcloud/core/installer"
+)
+
+type InstallFunc func() (installer.ReleaseResources, error)
+
+type dynamicTaskSlice struct {
+ t []Task
+}
+
+func (d *dynamicTaskSlice) Tasks() []Task {
+ return d.t
+}
+
+func (d *dynamicTaskSlice) Append(t Task) {
+ d.t = append(d.t, t)
+}
+
+func NewInstallTask(mon installer.HelmReleaseMonitor, fn InstallFunc) Task {
+ d := &dynamicTaskSlice{t: []Task{}}
+ var rr installer.ReleaseResources
+ done := make(chan error)
+ installTask := newLeafTask("Downloading configuration files", func() error {
+ var err error
+ rr, err = fn()
+ return err
+ })
+ d.Append(&installTask)
+ installTask.OnDone(func(err error) {
+ if err != nil {
+ done <- err
+ return
+ }
+ monTasks := NewMonitorReleaseTasks(mon, rr)
+ for _, mt := range monTasks {
+ d.Append(mt)
+ }
+ monitor := newConcurrentParentTask("Monitor", true, monTasks...)
+ monitor.OnDone(func(err error) {
+ done <- err
+ })
+ monitor.Start()
+ })
+ start := func() error {
+ installTask.Start()
+ return <-done
+ }
+ t := newParentTask("Installing application", true, start, d)
+ return &t
+}
diff --git a/core/installer/tasks/release.go b/core/installer/tasks/release.go
index 229d76e..9a99698 100644
--- a/core/installer/tasks/release.go
+++ b/core/installer/tasks/release.go
@@ -6,12 +6,16 @@
"github.com/giolekva/pcloud/core/installer"
)
-func NewMonitorRelease(mon installer.HelmReleaseMonitor, rr installer.ReleaseResources) Task {
+func NewMonitorReleaseTasks(mon installer.HelmReleaseMonitor, rr installer.ReleaseResources) []Task {
var t []Task
for _, h := range rr.Helm {
t = append(t, newMonitorHelm(mon, h))
}
- return newConcurrentParentTask("Monitor", true, t...)
+ return t
+}
+
+func NewMonitorRelease(mon installer.HelmReleaseMonitor, rr installer.ReleaseResources) Task {
+ return newConcurrentParentTask("Monitor", true, NewMonitorReleaseTasks(mon, rr)...)
}
func newMonitorHelm(mon installer.HelmReleaseMonitor, h installer.Resource) Task {
diff --git a/core/installer/tasks/tasks.go b/core/installer/tasks/tasks.go
index 3db7042..69ddd17 100644
--- a/core/installer/tasks/tasks.go
+++ b/core/installer/tasks/tasks.go
@@ -15,6 +15,10 @@
type TaskDoneListener func(err error)
+type Subtasks interface {
+ Tasks() []Task
+}
+
type Task interface {
Title() string
Start()
@@ -103,11 +107,17 @@
type parentTask struct {
leafTask
- subtasks []Task
+ subtasks Subtasks
showChildren bool
}
-func newParentTask(title string, showChildren bool, start func() error, subtasks ...Task) parentTask {
+type TaskSlice []Task
+
+func (s TaskSlice) Tasks() []Task {
+ return s
+}
+
+func newParentTask(title string, showChildren bool, start func() error, subtasks Subtasks) parentTask {
return parentTask{
leafTask: newLeafTask(title, start),
subtasks: subtasks,
@@ -117,17 +127,13 @@
func (t *parentTask) Subtasks() []Task {
if t.showChildren {
- return t.subtasks
+ return t.subtasks.Tasks()
} else {
return make([]Task, 0)
}
}
-type sequentialParentTask struct {
- parentTask
-}
-
-func newSequentialParentTask(title string, showChildren bool, subtasks ...Task) *sequentialParentTask {
+func newSequentialParentTask(title string, showChildren bool, subtasks ...Task) *parentTask {
start := func() error {
errCh := make(chan error)
for i := range subtasks[:len(subtasks)-1] {
@@ -146,16 +152,11 @@
go subtasks[0].Start()
return <-errCh
}
- return &sequentialParentTask{
- parentTask: newParentTask(title, showChildren, start, subtasks...),
- }
+ t := newParentTask(title, showChildren, start, TaskSlice(subtasks))
+ return &t
}
-type concurrentParentTask struct {
- parentTask
-}
-
-func newConcurrentParentTask(title string, showChildren bool, subtasks ...Task) *concurrentParentTask {
+func newConcurrentParentTask(title string, showChildren bool, subtasks ...Task) *parentTask {
start := func() error {
errCh := make(chan error)
for i := range subtasks {
@@ -177,7 +178,6 @@
}
return nil
}
- return &concurrentParentTask{
- parentTask: newParentTask(title, showChildren, start, subtasks...),
- }
+ t := newParentTask(title, showChildren, start, TaskSlice(subtasks))
+ return &t
}