sqlite3.connect가 메모리를 많이 잡아 먹네..

시은아빠·2021년 8월 27일
0

python 머냐 이건

목록 보기
1/1

DB접근이 필요할때 그때, 그때 connect하고 instance죽을때 close잘해주면 별 문제 없을 줄 알았더니.. 프로그램이 메모리를 무한정 먹네.. ㅡ.ㅡ

그래서 singleton형태로 connection을 관리해야겠다 생각했더니.. 만들고자 하는 프로그램이 적어도 3개의 thread가 필요하네...

그래서, singleton형태를 다루는 곳에서 thread id별로 connection을 singleton으로 관리할 수 있도록 하니, 메모리 누수가 더이상 없네..

import threading

class PoolSingleton:
    # {
    #   'obj': instance
    #   'run': [True|False]
    #   'tid': thread id
    # }
    __instance: list[dict] = []
    __MAX = 3

    @classmethod
    def __getInstance(cls):
        for instance in cls.__instance:
            if instance['tid'] == threading.get_ident():
                DEBUG(f"현재 thread instance 있음 [{instance}] [{threading.get_ident()}]")
                return instance['obj']
        ERROR(f"instance 없음  th:[{threading.get_ident()}]")
        cls.print_status()
        return None

    @classmethod
    def print_status(cls):
        for i, instance in enumerate(cls.__instance):
            print(f" {i}th pool = [{instance}]")

    @classmethod
    def instance(cls, *args, **kargs):
        # 가용Pool확인
        #instance = cls.__getAvailableInstance()
        instance = cls.__getInstance()

        # 해당 thread에 맞는 Pool이 없다면 추가 slot이 남아 있나?
        if not instance:
            DEBUG(f"가용 instance 없음 [{threading.get_ident()}]")
            # Max 확인
            if len(cls.__instance) < cls.__MAX:
                # Max에 도달되지 않으면 instance생성하여 Pool에 추가
                instance_dict = {
                    "obj": cls(*args, **kargs),
                    "tid": threading.get_ident(),
                    "run": True,
                }

                cls.__instance.append(instance_dict)
                INFO(f"instance 추가 [{threading.get_ident()}]")
                
                return instance_dict['obj']
            else:
                # 가용Pool도 없고 추가 slot도 없으면, Error 발생
                raise Error("가용Pool이 남아 있지 않습니다.")
        
        return instance

class DBPool(PoolSingleton):
    def __init__(self):
        self.db_path = "data/log.db"
        self.dbconn = sqlite3.connect(self.db_path)

# 사용할땐 이렇게
d1 = DBPool.instance()
d2 = DBPool.instance()
profile
생활 코더?

0개의 댓글