| OLD | NEW |
| (Empty) | |
| 1 // launchpad.net/juju/state |
| 2 // |
| 3 // Copyright (c) 2011-2012 Canonical Ltd. |
| 4 package state |
| 5 |
| 6 import ( |
| 7 "fmt" |
| 8 "launchpad.net/juju/go/state/presence" |
| 9 "time" |
| 10 ) |
| 11 |
| 12 const ( |
| 13 agentPingerPeriod = 25 * time.Millisecond |
| 14 agentWaitTimeout = 4 * agentPingerPeriod |
| 15 ) |
| 16 |
| 17 // AgentMixin has to be implemented by those state entities |
| 18 // which will have agent processes. |
| 19 type AgentMixin interface { |
| 20 // AgentConnected returns true if this entity state has an agent connect
ed. |
| 21 AgentConnected() (bool, error) |
| 22 // WaitAgentConnected waits until an agent has connected. |
| 23 WaitAgentConnected() error |
| 24 // ConnectAgent informs juju that this associated agent is alive. |
| 25 ConnectAgent() error |
| 26 // DisconnectAgent informs juju that this associated agent stops working
. |
| 27 DisconnectAgent() error |
| 28 } |
| 29 |
| 30 type agentMixin struct { |
| 31 st *State |
| 32 path string |
| 33 pinger *presence.Pinger |
| 34 } |
| 35 |
| 36 func newAgentMixin(st *State, path string) *agentMixin { |
| 37 return &agentMixin{st, path, nil} |
| 38 } |
| 39 |
| 40 // connected is a helper to implement the AgentConnected() method. |
| 41 func (am *agentMixin) connected() (bool, error) { |
| 42 return presence.Alive(am.st.zk, am.path) |
| 43 } |
| 44 |
| 45 // waitConnected is a helper to implement the WaitAgentConnected() method. |
| 46 func (am *agentMixin) waitConnected() error { |
| 47 alive, watch, err := presence.AliveW(am.st.zk, am.path) |
| 48 if err != nil { |
| 49 return err |
| 50 } |
| 51 // Quick return if already connected. |
| 52 if alive { |
| 53 return nil |
| 54 } |
| 55 // Wait for connection with timeout. |
| 56 select { |
| 57 case alive, ok := <-watch: |
| 58 if !ok { |
| 59 return fmt.Errorf("wait connection closed") |
| 60 } |
| 61 if !alive { |
| 62 return fmt.Errorf("not connected, must not happen") |
| 63 } |
| 64 case <-time.After(agentWaitTimeout): |
| 65 return fmt.Errorf("wait for connected agent timed out") |
| 66 } |
| 67 return nil |
| 68 } |
| 69 |
| 70 // connectAgent is a helper to implement the ConnectAgent() method. |
| 71 func (am *agentMixin) connect() (err error) { |
| 72 if am.pinger != nil { |
| 73 return fmt.Errorf("agent is already connected") |
| 74 } |
| 75 am.pinger, err = presence.StartPinger(am.st.zk, am.path, agentPingerPeri
od) |
| 76 return |
| 77 } |
| 78 |
| 79 // disconnectAgent is a helper to implement the DisconnectAgent() method. |
| 80 func (am *agentMixin) disconnect() error { |
| 81 if am.pinger == nil { |
| 82 return fmt.Errorf("agent is not connected") |
| 83 } |
| 84 am.pinger.Kill() |
| 85 am.pinger = nil |
| 86 return nil |
| 87 } |
| OLD | NEW |