2012-10-28

pyspa 2012-10 3日目 〜リファクタリング〜

眠い...

昨日はチューニングっぽいことをした後、眠りにつきました。今日はもう直接仕事をするのではなく、コードのエントロピィを下げる作業をしました。

たとえば、テストコードを見てもらったときに「これは、mock.patch を使いすぎだろwww」と指摘された箇所があります。

class API_UpdateCountsTest(TestBedTestCase):
    @patch('poll.api.get')
    @patch('backend.api.update_options_in_datastore')
    @patch('backend.api.calculate_deltas')
    @patch('google.appengine.api.taskqueue.Queue')
    def test(self, Queue, calculate, update, get_poll):
        ...
        self.assertEqual(Queue.call_count, 3)
        self.assertEqual(Queue.call_args_list[0], ((backend_api.QUEUE_NAMES[0],), {}))
        self.assertEqual(queue.lease_tasks.call_count, 2)
        self.assertEqual(queue.lease_tasks.call_args, ((backend_api.LEASE_SECONDS, backend_api.MAX_TASKS),  {}))
        ... (以下、大量の assert)

まあ、ひどい。テスト対象の関数の中で、いろんなことをしていて、かつ、それが丸見えになっているのが原因です。手順が多いのは仕方ないのだけれど、データの受け渡しがたくさん丸見えなのがよくない。

def _update_counts(queue_id):
    queue_name = QUEUE_NAMES[queue_id]
    queue = taskqueue.Queue(queue_name)
    tasks = queue.lease_tasks(LEASE_SECONDS, MAX_TASKS)
    vote_count = len(tasks)
    option_count = 0
    if tasks:
        payloads = [json.loads(task.payload) for task in tasks]
        deltas = calculate_deltas(payloads)
        option_count = len(deltas)
        update_options_in_datastore(deltas)
        # handle done
        for data in payloads:
            ... (まさかの20行くらい)...
        # delete task
        queue.delete_tasks(tasks)


ひどす。急ぎで性能を上げるために、コードを追加/削除/変更をしたときに、とにかくテストを書いて通すようにした残骸が残っています。こうやってエントロピィが増加するわけです。エントロピィの意味分かってませんが。

というわけで、以下のように変更。

def _update_counts(queue_id):
    data = dequeue(queue_id)
    if not tasks:
        return
    update_options(data)
    update_dones(data)

それでも patch は 3つくらい必要ですが、assert がシンプルになります。

そんな作業をしていたら、夜が明け、海辺まで散歩し、温泉に浸かり、朝食を食べて、もうすぐ10時になります。解散して、帰宅して寝ます。