개발일기는 사실상 일기라기보다 주제에 대한 생각을 끄적인것이며,
주제가 닫힌 순서대로 포스팅합니다.
내용의 정확성은 보장하지 않습니다.
테스트 할때 기본 데이터를 넣어야 할 때가 있다.
보통 테스트 환경은 빈 DB로 하는 경우가 많기 때문이다.
크롤러를 만들때는 factory_boy를 사용해서 만들었지만, 아무래도 좀 무겁다는 단점이 있다.
그리고 솔직히 잘 못쓰겠다. 연관관계를 매핑해줄 때 좀 까다로웠다.
그래서, 이번에는 내가 팩토리 메서드를 만들어 보기로 했다.
(사실 fastapi 예제에서 이런 방식으로 만들어서 쓰고 있었다 하하)
그런데 바로 문제가 생겼다.
GameScreenshot은 steam_file_id를 갖게 되는데, 이는 유니크 해야 하기 때문이다.
단순히 팩토리 메서드가 있는 모듈에 카운터를 만들어서 1씩 증가 하면 안될까? 싶었지만.
각 테스트는 병렬로 실행되기 때문에, 좀 곤란했다. 카운터에 racing condition이 걸린다면 추후에 애로사항이 될지 모른다.
그럼 어떻게 해야 하는가?
theading의 Lock을 쓰려고 했지만, 좀 더 코루틴에 걸맞는 asyncio의 Lock을 쓰는 방법도 있길래 이걸 택했다.
https://docs.python.org/ko/3/library/asyncio-sync.html
하지만 단점도 물론 있다!
이걸 사용하는 함수는 코루틴 함수여야 한다… 굳이 코루틴이지 않아도 되는데 코루틴이 된다.
그래도 큰 문제는 없으니 괜찮은 것 같다. :)
그래서 이렇게 된다.
steam_file_id_counter = 0
steam_file_id_lock = Lock()
async def create_random_game_screenshot(game_id: int | None) -> GameScreenshot:
global steam_file_id_counter
if game_id is None:
game = await create_random_game()
game_id = game.id
with Session(engine) as session:
async with steam_file_id_lock:
steam_file_id_counter += 1
screenshot = GameScreenshot(steam_file_id=steam_file_id_counter, url=random_url(), game_id=game_id)
session.add(screenshot)
session.commit()
session.refresh(screenshot)
return screenshot
'프로그래밍 > 스팀 게임 퀴즈' 카테고리의 다른 글
# 12 백엔드 코드를 비동기로 바꾸다. (0) | 2024.01.08 |
---|---|
#8 HttpUrl vs str (0) | 2023.12.30 |
#7 테스트 코드 내 세션 관리 (0) | 2023.12.29 |
#6 퀴즈 정답 제출은 어떻게 할까? (0) | 2023.12.28 |
#3 DB 세션에 대한 문제 (1) | 2023.12.25 |