Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2)

Delta Between Two Patch Sets: state/api/apiclient.go

Issue 9811044: state/api: Client connection health monitoring (Closed)
Left Patch Set: state/api: Support Ping() and SetDeadline() Created 11 years, 10 months ago
Right Patch Set: state/api: Client connection health monitoring Created 11 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « [revision details] ('k') | state/api/apierror.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2012, 2013 Canonical Ltd. 1 // Copyright 2012, 2013 Canonical Ltd.
2 // Licensed under the AGPLv3, see LICENCE file for details. 2 // Licensed under the AGPLv3, see LICENCE file for details.
3 3
4 package api 4 package api
5 5
6 import ( 6 import (
7 "code.google.com/p/go.net/websocket" 7 "code.google.com/p/go.net/websocket"
8 "crypto/tls" 8 "crypto/tls"
9 "crypto/x509" 9 "crypto/x509"
10 "launchpad.net/juju-core/cert" 10 "launchpad.net/juju-core/cert"
11 "launchpad.net/juju-core/log" 11 "launchpad.net/juju-core/log"
12 "launchpad.net/juju-core/rpc" 12 "launchpad.net/juju-core/rpc"
13 "launchpad.net/juju-core/rpc/jsoncodec" 13 "launchpad.net/juju-core/rpc/jsoncodec"
14 "launchpad.net/juju-core/utils" 14 "launchpad.net/juju-core/utils"
15 "time" 15 "time"
16 ) 16 )
17 17
18 // PingFrequency defines how often the internal connection health 18 // PingPeriod defines how often the internal connection health check
19 // check will run. 19 // will run. It's a variable so it can be changed in tests.
20 const PingFrequency = 5 * time.Second 20 var PingPeriod = 5 * time.Second
fwereade 2013/05/28 07:11:21 PingPeriod please.
dimitern 2013/05/28 07:22:56 Done.
21 21
22 type State struct { 22 type State struct {
23 client *rpc.Conn 23 client *rpc.Conn
24 conn *websocket.Conn 24 conn *websocket.Conn
25 25
26 » // closed is a channel that gets closed when the connection is 26 » // broken is a channel that gets closed when the connection is
27 // broken. 27 // broken.
28 » closed chan struct{} 28 » broken chan struct{}
29 } 29 }
30 30
31 // Info encapsulates information about a server holding juju state and 31 // Info encapsulates information about a server holding juju state and
32 // can be used to make a connection to it. 32 // can be used to make a connection to it.
33 type Info struct { 33 type Info struct {
34 // Addrs holds the addresses of the state servers. 34 // Addrs holds the addresses of the state servers.
35 Addrs []string 35 Addrs []string
36 36
37 // CACert holds the CA certificate that will be used 37 // CACert holds the CA certificate that will be used
38 // to validate the state server's certificate, in PEM format. 38 // to validate the state server's certificate, in PEM format.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 st := &State{ 90 st := &State{
91 client: client, 91 client: client,
92 conn: conn, 92 conn: conn,
93 } 93 }
94 if info.Tag != "" || info.Password != "" { 94 if info.Tag != "" || info.Password != "" {
95 if err := st.Login(info.Tag, info.Password); err != nil { 95 if err := st.Login(info.Tag, info.Password); err != nil {
96 conn.Close() 96 conn.Close()
97 return nil, err 97 return nil, err
98 } 98 }
99 } 99 }
100 » st.closed = make(chan struct{}) 100 » st.broken = make(chan struct{})
101 » go st.healthMonitor() 101 » go st.heartbeatMonitor()
102 return st, nil 102 return st, nil
103 } 103 }
104 104
105 func (s *State) healthMonitor() { 105 func (s *State) heartbeatMonitor() {
106 ping := func() error { 106 ping := func() error {
107 return s.call("State", "", "Ping", nil, nil) 107 return s.call("State", "", "Ping", nil, nil)
108 } 108 }
109 for { 109 for {
110 if err := ping(); err != nil { 110 if err := ping(); err != nil {
111 » » » close(s.closed) 111 » » » close(s.broken)
112 return 112 return
113 } 113 }
114 » » time.Sleep(PingFrequency) 114 » » time.Sleep(PingPeriod)
115 } 115 }
116 } 116 }
117 117
118 func (s *State) call(objType, id, request string, params, response interface{}) error { 118 func (s *State) call(objType, id, request string, params, response interface{}) error {
119 err := s.client.Call(objType, id, request, params, response) 119 err := s.client.Call(objType, id, request, params, response)
120 return clientError(err) 120 return clientError(err)
121 } 121 }
122 122
123 func (s *State) Close() error { 123 func (s *State) Close() error {
124 return s.client.Close() 124 return s.client.Close()
125 } 125 }
126 126
127 // SetDeadlines set the connection's network read and write deadlines. 127 // Broken returns a channel that's closed when the connection is broken.
fwereade 2013/05/28 07:11:21 I'd prefer something like Broken rather than Close
dimitern 2013/05/28 07:22:56 Done.
128 func (s *State) Closed() <-chan struct{} { 128 func (s *State) Broken() <-chan struct{} {
129 » return s.closed 129 » return s.broken
130 } 130 }
131 131
132 // RPCClient returns the RPC client for the state, so that testing 132 // RPCClient returns the RPC client for the state, so that testing
133 // functions can tickle parts of the API that the conventional entry 133 // functions can tickle parts of the API that the conventional entry
134 // points don't reach. This is exported for testing purposes only. 134 // points don't reach. This is exported for testing purposes only.
135 func (s *State) RPCClient() *rpc.Conn { 135 func (s *State) RPCClient() *rpc.Conn {
136 return s.client 136 return s.client
137 } 137 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b