~juju-qa/ubuntu/trusty/juju/juju-1.25.8

« back to all changes in this revision

Viewing changes to src/github.com/juju/govmomi/govc/importx/lease_updater.go

  • Committer: Nicholas Skaggs
  • Date: 2016-12-02 18:01:10 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161202180110-dl1helep8qfebmhx
ImportĀ upstreamĀ 1.25.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2014 VMware, Inc. All Rights Reserved.
 
3
 
 
4
Licensed under the Apache License, Version 2.0 (the "License");
 
5
you may not use this file except in compliance with the License.
 
6
You may obtain a copy of the License at
 
7
 
 
8
    http://www.apache.org/licenses/LICENSE-2.0
 
9
 
 
10
Unless required by applicable law or agreed to in writing, software
 
11
distributed under the License is distributed on an "AS IS" BASIS,
 
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
See the License for the specific language governing permissions and
 
14
limitations under the License.
 
15
*/
 
16
 
 
17
package importx
 
18
 
 
19
import (
 
20
        "fmt"
 
21
        "net/url"
 
22
        "sync"
 
23
        "sync/atomic"
 
24
        "time"
 
25
 
 
26
        "github.com/juju/govmomi/object"
 
27
        "github.com/juju/govmomi/vim25"
 
28
        "github.com/juju/govmomi/vim25/progress"
 
29
        "github.com/juju/govmomi/vim25/types"
 
30
        "golang.org/x/net/context"
 
31
)
 
32
 
 
33
type ovfFileItem struct {
 
34
        url  *url.URL
 
35
        item types.OvfFileItem
 
36
        ch   chan progress.Report
 
37
}
 
38
 
 
39
func (o ovfFileItem) Sink() chan<- progress.Report {
 
40
        return o.ch
 
41
}
 
42
 
 
43
type leaseUpdater struct {
 
44
        client *vim25.Client
 
45
        lease  *object.HttpNfcLease
 
46
 
 
47
        pos   int64 // Number of bytes
 
48
        total int64 // Total number of bytes
 
49
 
 
50
        done chan struct{} // When lease updater should stop
 
51
 
 
52
        wg sync.WaitGroup // Track when update loop is done
 
53
}
 
54
 
 
55
func newLeaseUpdater(client *vim25.Client, lease *object.HttpNfcLease, items []ovfFileItem) *leaseUpdater {
 
56
        l := leaseUpdater{
 
57
                client: client,
 
58
                lease:  lease,
 
59
 
 
60
                done: make(chan struct{}),
 
61
        }
 
62
 
 
63
        for _, item := range items {
 
64
                l.total += item.item.Size
 
65
                go l.waitForProgress(item)
 
66
        }
 
67
 
 
68
        // Kickstart update loop
 
69
        l.wg.Add(1)
 
70
        go l.run()
 
71
 
 
72
        return &l
 
73
}
 
74
 
 
75
func (l *leaseUpdater) waitForProgress(item ovfFileItem) {
 
76
        var pos, total int64
 
77
 
 
78
        total = item.item.Size
 
79
 
 
80
        for {
 
81
                select {
 
82
                case <-l.done:
 
83
                        return
 
84
                case p, ok := <-item.ch:
 
85
                        // Return in case of error
 
86
                        if ok && p.Error() != nil {
 
87
                                return
 
88
                        }
 
89
 
 
90
                        if !ok {
 
91
                                // Last element on the channel, add to total
 
92
                                atomic.AddInt64(&l.pos, total-pos)
 
93
                                return
 
94
                        }
 
95
 
 
96
                        // Approximate progress in number of bytes
 
97
                        x := int64(float32(total) * (p.Percentage() / 100.0))
 
98
                        atomic.AddInt64(&l.pos, x-pos)
 
99
                        pos = x
 
100
                }
 
101
        }
 
102
}
 
103
 
 
104
func (l *leaseUpdater) run() {
 
105
        defer l.wg.Done()
 
106
 
 
107
        tick := time.NewTicker(2 * time.Second)
 
108
        defer tick.Stop()
 
109
 
 
110
        for {
 
111
                select {
 
112
                case <-l.done:
 
113
                        return
 
114
                case <-tick.C:
 
115
                        // From the vim api HttpNfcLeaseProgress(percent) doc, percent ==
 
116
                        // "Completion status represented as an integer in the 0-100 range."
 
117
                        // Always report the current value of percent, as it will renew the
 
118
                        // lease even if the value hasn't changed or is 0.
 
119
                        percent := int(float32(100*atomic.LoadInt64(&l.pos)) / float32(l.total))
 
120
                        err := l.lease.HttpNfcLeaseProgress(context.TODO(), percent)
 
121
                        if err != nil {
 
122
                                fmt.Printf("from lease updater: %s\n", err)
 
123
                        }
 
124
                }
 
125
        }
 
126
}
 
127
 
 
128
func (l *leaseUpdater) Done() {
 
129
        close(l.done)
 
130
        l.wg.Wait()
 
131
}