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()