Conditions | 22 |
Total Lines | 138 |
Lines | 0 |
Ratio | 0 % |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like GlancesClientBrowser.__serve_forever() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # -*- coding: utf-8 -*- |
||
93 | def __serve_forever(self): |
||
94 | """Main client loop.""" |
||
95 | while True: |
||
96 | # No need to update the server list |
||
97 | # It's done by the GlancesAutoDiscoverListener class (autodiscover.py) |
||
98 | # Or define staticaly in the configuration file (module static_list.py) |
||
99 | # For each server in the list, grab elementary stats (CPU, LOAD, MEM, OS...) |
||
100 | # logger.debug(self.get_servers_list()) |
||
101 | try: |
||
102 | for v in self.get_servers_list(): |
||
103 | # Do not retreive stats for statics server |
||
104 | # Why ? Because for each offline servers, the timeout will be reached |
||
105 | # So ? The curse interface freezes |
||
106 | if v['type'] == 'STATIC' and v['status'] in ['UNKNOWN', 'SNMP', 'OFFLINE']: |
||
107 | continue |
||
108 | |||
109 | # Get the server URI |
||
110 | uri = self.__get_uri(v) |
||
111 | |||
112 | # Try to connect to the server |
||
113 | t = GlancesClientTransport() |
||
114 | t.set_timeout(3) |
||
115 | |||
116 | # Get common stats |
||
117 | try: |
||
118 | s = ServerProxy(uri, transport=t) |
||
119 | except Exception as e: |
||
120 | logger.warning( |
||
121 | "Client browser couldn't create socket {0}: {1}".format(uri, e)) |
||
122 | else: |
||
123 | # Mandatory stats |
||
124 | try: |
||
125 | # CPU% |
||
126 | cpu_percent = 100 - json.loads(s.getCpu())['idle'] |
||
127 | v['cpu_percent'] = '{0:.1f}'.format(cpu_percent) |
||
128 | # MEM% |
||
129 | v['mem_percent'] = json.loads(s.getMem())['percent'] |
||
130 | # OS (Human Readable name) |
||
131 | v['hr_name'] = json.loads(s.getSystem())['hr_name'] |
||
132 | except (socket.error, Fault, KeyError) as e: |
||
133 | logger.debug( |
||
134 | "Error while grabbing stats form {0}: {1}".format(uri, e)) |
||
135 | v['status'] = 'OFFLINE' |
||
136 | except ProtocolError as e: |
||
137 | if e.errcode == 401: |
||
138 | # Error 401 (Authentication failed) |
||
139 | # Password is not the good one... |
||
140 | v['password'] = None |
||
141 | v['status'] = 'PROTECTED' |
||
142 | else: |
||
143 | v['status'] = 'OFFLINE' |
||
144 | logger.debug("Cannot grab stats from {0} ({1} {2})".format(uri, e.errcode, e.errmsg)) |
||
145 | else: |
||
146 | # Status |
||
147 | v['status'] = 'ONLINE' |
||
148 | |||
149 | # Optional stats (load is not available on Windows OS) |
||
150 | try: |
||
151 | # LOAD |
||
152 | load_min5 = json.loads(s.getLoad())['min5'] |
||
153 | v['load_min5'] = '{0:.2f}'.format(load_min5) |
||
154 | except Exception as e: |
||
155 | logger.warning( |
||
156 | "Error while grabbing stats form {0}: {1}".format(uri, e)) |
||
157 | # List can change size during iteration... |
||
158 | except RuntimeError: |
||
159 | logger.debug( |
||
160 | "Server list dictionnary change inside the loop (wait next update)") |
||
161 | |||
162 | # Update the screen (list or Glances client) |
||
163 | if self.screen.active_server is None: |
||
164 | # Display the Glances browser |
||
165 | self.screen.update(self.get_servers_list()) |
||
166 | else: |
||
167 | # Display the Glances client for the selected server |
||
168 | logger.debug("Selected server: {0}".format(self.get_servers_list()[self.screen.active_server])) |
||
169 | |||
170 | # Connection can take time |
||
171 | # Display a popup |
||
172 | self.screen.display_popup( |
||
173 | 'Connect to {0}:{1}'.format(v['name'], v['port']), duration=1) |
||
174 | |||
175 | # A password is needed to access to the server's stats |
||
176 | if self.get_servers_list()[self.screen.active_server]['password'] is None: |
||
177 | # First of all, check if a password is available in the [passwords] section |
||
178 | clear_password = self.password.get_password(v['name']) |
||
179 | if (clear_password is None or self.get_servers_list() |
||
180 | [self.screen.active_server]['status'] == 'PROTECTED'): |
||
181 | # Else, the password should be enter by the user |
||
182 | # Display a popup to enter password |
||
183 | clear_password = self.screen.display_popup( |
||
184 | 'Password needed for {0}: '.format(v['name']), is_input=True) |
||
185 | # Store the password for the selected server |
||
186 | if clear_password is not None: |
||
187 | self.set_in_selected('password', self.password.sha256_hash(clear_password)) |
||
188 | |||
189 | # Display the Glance client on the selected server |
||
190 | logger.info("Connect Glances client to the {0} server".format( |
||
191 | self.get_servers_list()[self.screen.active_server]['key'])) |
||
192 | |||
193 | # Init the client |
||
194 | args_server = self.args |
||
195 | |||
196 | # Overwrite connection setting |
||
197 | args_server.client = self.get_servers_list()[self.screen.active_server]['ip'] |
||
198 | args_server.port = self.get_servers_list()[self.screen.active_server]['port'] |
||
199 | args_server.username = self.get_servers_list()[self.screen.active_server]['username'] |
||
200 | args_server.password = self.get_servers_list()[self.screen.active_server]['password'] |
||
201 | client = GlancesClient(config=self.config, args=args_server, return_to_browser=True) |
||
202 | |||
203 | # Test if client and server are in the same major version |
||
204 | if not client.login(): |
||
205 | self.screen.display_popup( |
||
206 | "Sorry, cannot connect to '{0}'\n" |
||
207 | "See 'glances.log' for more details".format(v['name'])) |
||
208 | |||
209 | # Set the ONLINE status for the selected server |
||
210 | self.set_in_selected('status', 'OFFLINE') |
||
211 | else: |
||
212 | # Start the client loop |
||
213 | # Return connection type: 'glances' or 'snmp' |
||
214 | connection_type = client.serve_forever() |
||
215 | |||
216 | try: |
||
217 | logger.debug("Disconnect Glances client from the {0} server".format( |
||
218 | self.get_servers_list()[self.screen.active_server]['key'])) |
||
219 | except IndexError: |
||
220 | # Server did not exist anymore |
||
221 | pass |
||
222 | else: |
||
223 | # Set the ONLINE status for the selected server |
||
224 | if connection_type == 'snmp': |
||
225 | self.set_in_selected('status', 'SNMP') |
||
226 | else: |
||
227 | self.set_in_selected('status', 'ONLINE') |
||
228 | |||
229 | # Return to the browser (no server selected) |
||
230 | self.screen.active_server = None |
||
231 | |||
256 |