Conditions | 22 |
Total Lines | 119 |
Code Lines | 91 |
Lines | 0 |
Ratio | 0 % |
Changes | 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 exabgp.application.pipe.Control.loop() 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 | import os |
||
143 | def loop(self): |
||
144 | try: |
||
145 | self.r_pipe = os.open(self.recv, os.O_RDWR | os.O_NONBLOCK | os.O_EXCL) |
||
146 | except OSError: |
||
147 | self.terminate() |
||
148 | |||
149 | standard_in = sys.stdin.fileno() |
||
150 | standard_out = sys.stdout.fileno() |
||
151 | |||
152 | def monitor(function): |
||
153 | def wrapper(*args): |
||
154 | r = function(*args) |
||
155 | return r |
||
156 | |||
157 | return wrapper |
||
158 | |||
159 | @monitor |
||
160 | def std_reader(number): |
||
161 | try: |
||
162 | return os.read(standard_in, number) |
||
163 | except OSError as exc: |
||
164 | if exc.errno in error.block: |
||
165 | return '' |
||
166 | sys.exit(1) |
||
167 | |||
168 | @monitor |
||
169 | def std_writer(line): |
||
170 | try: |
||
171 | return os.write(standard_out, line) |
||
172 | except OSError as exc: |
||
173 | if exc.errno in error.block: |
||
174 | return 0 |
||
175 | sys.exit(1) |
||
176 | |||
177 | @monitor |
||
178 | def fifo_reader(number): |
||
179 | try: |
||
180 | return os.read(self.r_pipe, number) |
||
181 | except OSError as exc: |
||
182 | if exc.errno in error.block: |
||
183 | return '' |
||
184 | sys.exit(1) |
||
185 | |||
186 | @monitor |
||
187 | def fifo_writer(line): |
||
188 | pipe, nb = None, 0 |
||
189 | try: |
||
190 | pipe = os.open(self.send, os.O_WRONLY | os.O_NONBLOCK | os.O_EXCL) |
||
191 | self.no_buffer(pipe) |
||
192 | except OSError: |
||
193 | time.sleep(0.05) |
||
194 | return 0 |
||
195 | if pipe is not None: |
||
196 | try: |
||
197 | nb = os.write(pipe, line) |
||
198 | except OSError: |
||
199 | pass |
||
200 | try: |
||
201 | os.close(pipe) |
||
202 | except OSError: |
||
203 | pass |
||
204 | return nb |
||
205 | |||
206 | read = { |
||
207 | standard_in: std_reader, |
||
208 | self.r_pipe: fifo_reader, |
||
209 | } |
||
210 | |||
211 | write = { |
||
212 | standard_in: fifo_writer, |
||
213 | self.r_pipe: std_writer, |
||
214 | } |
||
215 | |||
216 | backlog = { |
||
217 | standard_in: deque(), |
||
218 | self.r_pipe: deque(), |
||
219 | } |
||
220 | |||
221 | store = { |
||
222 | standard_in: b'', |
||
223 | self.r_pipe: b'', |
||
224 | } |
||
225 | |||
226 | def consume(source): |
||
227 | if not backlog[source] and b'\n' not in store[source]: |
||
|
|||
228 | store[source] += read[source](1024) |
||
229 | else: |
||
230 | backlog[source].append(read[source](1024)) |
||
231 | # assuming a route takes 80 chars, 100 Mb is over 1Millions routes |
||
232 | # something is really wrong if it was not consummed |
||
233 | if len(backlog) > 100 * mb: |
||
234 | sys.stderr.write('using too much memory - exiting') |
||
235 | sys.exit(1) |
||
236 | |||
237 | reading = [standard_in, self.r_pipe] |
||
238 | |||
239 | while True: |
||
240 | ready = self.read_on(reading) |
||
241 | |||
242 | # command from user |
||
243 | if self.r_pipe in ready: |
||
244 | consume(self.r_pipe) |
||
245 | if standard_in in ready: |
||
246 | consume(standard_in) |
||
247 | |||
248 | for source in reading: |
||
249 | while b'\n' in store[source]: |
||
250 | line, _ = store[source].split(b'\n', 1) |
||
251 | # sys.stderr.write(str(line).replace('\n','\\n') + '\n') |
||
252 | # sys.stderr.flush() |
||
253 | sent = write[source](line + b'\n') |
||
254 | # sys.stderr.write('sent %d\n' % sent) |
||
255 | # sys.stderr.flush() |
||
256 | if sent: |
||
257 | store[source] = store[source][sent:] |
||
258 | continue |
||
259 | break |
||
260 | if backlog[source]: |
||
261 | store[source] += backlog[source].popleft() |
||
262 | |||
294 |