프로젝트/COHO - 코인 호재 캘린더

[Django] 코호 - 실시간 코인 호재 캘린더 PROC 10

모영이 2021. 4. 1. 14:44

이번주 배포가 목표다. 계획상 내일 배포를 해야하지만, 많이 부족하다. 일단 배포를 해보고 업데이트 하는걸로 하려고 한다. 배포 안하고 계속 수정만 한다면 보이는 결과가 없어서 힘이 빠질 것 같기 때문이다. 3주가 개발에 있어서는 짧지만 우리가 하는 프로젝트의 크기를 생각했을 때, 3주면 결과를 내야한다고 생각한다. 다음주에는 모바일 배포가 목표인데, 간단히 웹뷰만 띄워서 배포하는게 목표다.

해결한 문제

멀티 프로세스와 멀티 스레드를 동시에 사용해서 속도를 90초에서 60초로 줄였다. 하지만 멀티 프로세스가 잘 동작하지 않는 것 같아서 조금 더 해결해야 할 것 같다. 또한 속도를 더 줄일 수 있는 방법을 계속 찾아볼 것이다.

 

아래의 블로그에서 참고했다. 단순 멀티 스레드 속도가 멀티 프로세스보다 속도가 더 빨랐다. 하지만 두개 동시에 사용했을 때 속도차이가 나지 않았다. 뭐가 문제인지는 계속 알아봐야겠다.

여기 사이트

마주친 문제

멀티 프로세스를 사용할 때 인자의 값의 개수가 제한적이었다. pool.map을 사용하게 되면 인자를 1개 밖에 못쓰기 때문에 다른 방법을 찾아서 인자의 제한을 해결해야 했다. multi_run_wapper 함수를 만들어서 인자 여러개를 한개처럼 넘겨주는 트릭을 사용했다. 이건 스택오버플로우 돌아다니다 발견한 코드다.

해결해야 할 문제

계속 코드를 긁어오다보니깐 많이 지저분해졌다. 깔끔하게 필요한 것만 남기고 지우고, 비효율적인 코드를 찾아서 수정할 거다. 

멀티 프로세스 코드를 수정해서 속도를 더 줄일 것이다. 60초면 많이 줄인 것이긴 하지만, 2개 사이트뿐만 아니라 더 많은 사이트 크롤링을 할 것이기 때문에 속도를 더 줄여야 한다.

 

parser.py

import concurrent
import json
import collections
import multiprocessing
import time
from concurrent.futures.thread import ThreadPoolExecutor

import crawl_coinmarketcal as coinmarketcal
import crawl_coinscalendar as coinscalendar
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "websaver.settings")
import django
django.setup()
from parsed_data.models import BlogData
global result
def preprocessingDict(dic: dict):
    coin_dict = collections.defaultdict(dict)
    for key, value in dic.items():
        if value['symbol'] in coin_dict[value['date']]:
            coin_dict[value['date']][value['symbol']].append([key, value['title'], value['name']])
        else:
            coin_dict[value['date']][value['symbol']] = [[key, value['title'], value['name']]]
    return coin_dict

def multi_run_wrapper(args):
    do_process_with_thread_crawl(*args)

def do_process_with_thread_crawl(result):
    do_thread_crawl(coinmarketcal.get_urls(), coinscalendar.get_urls(), result)

def do_thread_crawl(urls1: list, urls2, result: dict):
    thread_list = []

    with ThreadPoolExecutor(max_workers=16) as executor:
        for url in urls2:
            thread_list.append(executor.submit(coinscalendar.do_crawl, (url, result)))
        for url in urls1:
            thread_list.append(executor.submit(coinmarketcal.do_crawl, (url, result)))
        for execution in concurrent.futures.as_completed(thread_list):
            execution.result()


if __name__ == '__main__':
    start_time = time.time()
    manager = multiprocessing.Manager()
    result = manager.dict()

    proc = multiprocessing.Process(target=do_thread_crawl, args=(coinmarketcal.get_urls(), coinscalendar.get_urls(), result))
    proc.start()
    proc.join()
    print(time.time() - start_time)
    # print(json.dumps(preprocessingDict(result.copy()), indent="\t"))
    # for t, l in result.items():
    #     BlogData(title=t, link=l).save()