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