1
// Copyright 2014 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
9
"github.com/juju/ratelimit"
12
"launchpad.net/juju-core/environs"
13
"launchpad.net/juju-core/errors"
14
"launchpad.net/juju-core/instance"
17
type instanceGetter interface {
18
Instances(ids []instance.Id) ([]instance.Instance, error)
21
type aggregator struct {
22
environ instanceGetter
23
reqc chan instanceInfoReq
27
func newAggregator(env instanceGetter) *aggregator {
30
reqc: make(chan instanceInfoReq),
39
type instanceInfoReq struct {
41
reply chan<- instanceInfoReply
44
type instanceInfoReply struct {
49
func (a *aggregator) instanceInfo(id instance.Id) (instanceInfo, error) {
50
reply := make(chan instanceInfoReply)
51
a.reqc <- instanceInfoReq{
59
var gatherTime = 3 * time.Second
61
func (a *aggregator) loop() error {
62
timer := time.NewTimer(0)
64
var reqs []instanceInfoReq
65
// We use a capacity of 1 so that sporadic requests will
66
// be serviced immediately without having to wait.
67
bucket := ratelimit.New(gatherTime, 1)
70
case <-a.tomb.Dying():
74
waitTime := bucket.Take(1)
77
reqs = append(reqs, req)
79
ids := make([]instance.Id, len(reqs))
80
for i, req := range reqs {
83
insts, err := a.environ.Instances(ids)
84
for i, req := range reqs {
85
var reply instanceInfoReply
86
if err != nil && err != environs.ErrPartialInstances {
89
reply.info, reply.err = a.instInfo(req.instId, insts[i])
98
// instInfo returns the instance info for the given id
99
// and instance. If inst is nil, it returns a not-found error.
100
func (*aggregator) instInfo(id instance.Id, inst instance.Instance) (instanceInfo, error) {
102
return instanceInfo{}, errors.NotFoundf("instance %v", id)
104
addr, err := inst.Addresses()
106
return instanceInfo{}, err
114
func (a *aggregator) Kill() {
118
func (a *aggregator) Wait() error {