| Conditions | 20 |
| Total Lines | 102 |
| 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 Processor.on_task() 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 | #!/usr/bin/env python |
||
| 99 | def on_task(self, task, response): |
||
| 100 | '''Deal one task''' |
||
| 101 | start_time = time.time() |
||
| 102 | response = rebuild_response(response) |
||
| 103 | |||
| 104 | try: |
||
| 105 | assert 'taskid' in task, 'need taskid in task' |
||
| 106 | project = task['project'] |
||
| 107 | updatetime = task.get('project_updatetime', None) |
||
| 108 | md5sum = task.get('project_md5sum', None) |
||
| 109 | project_data = self.project_manager.get(project, updatetime, md5sum) |
||
| 110 | assert project_data, "no such project!" |
||
| 111 | if project_data.get('exception'): |
||
| 112 | ret = ProcessorResult(logs=(project_data.get('exception_log'), ), |
||
| 113 | exception=project_data['exception']) |
||
| 114 | else: |
||
| 115 | ret = project_data['instance'].run_task( |
||
| 116 | project_data['module'], task, response) |
||
| 117 | except Exception as e: |
||
| 118 | logstr = traceback.format_exc() |
||
| 119 | ret = ProcessorResult(logs=(logstr, ), exception=e) |
||
| 120 | process_time = time.time() - start_time |
||
| 121 | |||
| 122 | if not ret.extinfo.get('not_send_status', False): |
||
| 123 | if ret.exception: |
||
| 124 | track_headers = dict(response.headers) |
||
| 125 | else: |
||
| 126 | track_headers = {} |
||
| 127 | for name in ('etag', 'last-modified'): |
||
| 128 | if name not in response.headers: |
||
| 129 | continue |
||
| 130 | track_headers[name] = response.headers[name] |
||
| 131 | |||
| 132 | status_pack = { |
||
| 133 | 'taskid': task['taskid'], |
||
| 134 | 'project': task['project'], |
||
| 135 | 'url': task.get('url'), |
||
| 136 | 'track': { |
||
| 137 | 'fetch': { |
||
| 138 | 'ok': response.isok(), |
||
| 139 | 'redirect_url': response.url if response.url != response.orig_url else None, |
||
| 140 | 'time': response.time, |
||
| 141 | 'error': response.error, |
||
| 142 | 'status_code': response.status_code, |
||
| 143 | 'encoding': response.encoding, |
||
| 144 | 'headers': track_headers, |
||
| 145 | 'content': response.text[:500] if ret.exception else None, |
||
| 146 | }, |
||
| 147 | 'process': { |
||
| 148 | 'ok': not ret.exception, |
||
| 149 | 'time': process_time, |
||
| 150 | 'follows': len(ret.follows), |
||
| 151 | 'result': ( |
||
| 152 | None if ret.result is None |
||
| 153 | else utils.text(ret.result)[:self.RESULT_RESULT_LIMIT] |
||
| 154 | ), |
||
| 155 | 'logs': ret.logstr()[-self.RESULT_LOGS_LIMIT:], |
||
| 156 | 'exception': ret.exception, |
||
| 157 | }, |
||
| 158 | 'save': ret.save, |
||
| 159 | }, |
||
| 160 | } |
||
| 161 | if 'schedule' in task: |
||
| 162 | status_pack['schedule'] = task['schedule'] |
||
| 163 | |||
| 164 | # FIXME: unicode_obj should used in scheduler before store to database |
||
| 165 | # it's used here for performance. |
||
| 166 | self.status_queue.put(utils.unicode_obj(status_pack)) |
||
| 167 | |||
| 168 | # FIXME: unicode_obj should used in scheduler before store to database |
||
| 169 | # it's used here for performance. |
||
| 170 | if ret.follows: |
||
| 171 | for each in (ret.follows[x:x + 1000] for x in range(0, len(ret.follows), 1000)): |
||
| 172 | self.newtask_queue.put([utils.unicode_obj(newtask) for newtask in each]) |
||
| 173 | |||
| 174 | for project, msg, url in ret.messages: |
||
| 175 | try: |
||
| 176 | self.on_task({ |
||
| 177 | 'taskid': utils.md5string(url), |
||
| 178 | 'project': project, |
||
| 179 | 'url': url, |
||
| 180 | 'process': { |
||
| 181 | 'callback': '_on_message', |
||
| 182 | } |
||
| 183 | }, { |
||
| 184 | 'status_code': 200, |
||
| 185 | 'url': url, |
||
| 186 | 'save': (task['project'], msg), |
||
| 187 | }) |
||
| 188 | except Exception as e: |
||
| 189 | logger.exception('Sending message error.') |
||
| 190 | continue |
||
| 191 | |||
| 192 | if ret.exception: |
||
| 193 | logger_func = logger.error |
||
| 194 | else: |
||
| 195 | logger_func = logger.info |
||
| 196 | logger_func('process %s:%s %s -> [%d] len:%d -> result:%.10r fol:%d msg:%d err:%r' % ( |
||
| 197 | task['project'], task['taskid'], |
||
| 198 | task.get('url'), response.status_code, len(response.content), |
||
| 199 | ret.result, len(ret.follows), len(ret.messages), ret.exception)) |
||
| 200 | return True |
||
| 201 | |||
| 227 |