Skip to content

Commit

Permalink
examples: add ListView example for waiting on updates to tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
dougm committed Sep 28, 2023
1 parent 3741df6 commit f2aaee5
Showing 1 changed file with 70 additions and 0 deletions.
70 changes: 70 additions & 0 deletions view/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ import (
"fmt"
"log"
"sort"
"sync"

"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/simulator"
"github.com/vmware/govmomi/view"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)

// Create a view of all hosts in the inventory, printing host names that belong to a cluster and excluding standalone hosts.
Expand Down Expand Up @@ -174,3 +177,70 @@ func ExampleContainerView_Find() {
}, model)
// Output: 4
}

// This example uses a single PropertyCollector with ListView for waiting on updates to N tasks
func ExampleListView_tasks() {
simulator.Run(func(ctx context.Context, c *vim25.Client) error {
list, err := view.NewManager(c).CreateListView(ctx, nil)
if err != nil {
return err
}

defer list.Destroy(ctx)

vms, err := find.NewFinder(c).VirtualMachineList(ctx, "*")
if err != nil {
return err
}

result := map[types.TaskInfoState]int{}
n := len(vms)
p := property.DefaultCollector(c)

// wait for any updates to tasks in our list view
filter := new(property.WaitFilter).Add(list.Reference(), "Task", []string{"info"}, list.TraversalSpec())

var werr error
var wg sync.WaitGroup
wg.Add(n)
go func() { // WaitForUpdates blocks until func returns true
werr = property.WaitForUpdates(ctx, p, filter, func(updates []types.ObjectUpdate) bool {
for _, update := range updates {
for _, change := range update.ChangeSet {
info := change.Val.(types.TaskInfo)

switch info.State {
case types.TaskInfoStateSuccess, types.TaskInfoStateError:
_ = list.Remove(ctx, []types.ManagedObjectReference{update.Obj})
result[info.State]++
n--
wg.Done()
}
}
}

return n == 0
})
}()

for _, vm := range vms {
task, err := vm.PowerOff(ctx)
if err != nil {
return err
}
err = list.Add(ctx, []types.ManagedObjectReference{task.Reference()})
if err != nil {
return err
}
}

wg.Wait() // wait until all tasks complete and WaitForUpdates returns

for state, n := range result {
fmt.Printf("%s=%d", state, n)
}

return werr
})
// Output: success=4
}

0 comments on commit f2aaee5

Please sign in to comment.