2021-gpu-is-mine
2021-gpu-is-mine copied to clipboard
Job 도메인 설계에 대해 고민해본다.
이슈 설명
도메인 구조에 대해 다시 한 번 고민해 본다.
패키지 간에 도메인 그래프를 그려보고 서로의 의존관계를 그래프로 그려보고 방향성에 대해 고민해 본다.
지금 당장 수정한다라기보다는, 구조에 대해 고민해보는 것.
이번 이슈는 Job에 대해서만으로 한정한다.
참고자료 조영호님 우아한 객체지향 발표
@Transactional
public Long save(Long memberId, JobRequest jobRequest) {
//패키지간의 의존 관계를 끊어야 한다.
// A라는 패키지의 로직을 수정했을 때, B를 수정해야됨, A를 수정해야 됨, B를 수정해야 됨.
// job을 이루는 서버한테 이 Member가 이 서버쓸수 있어? 라고 메시지를 보내야 한다.
// Service에서 모든 로직을 처리하고 있는 느낌.
memberService.checkMemberOfServer(memberId, jobRequest.getGpuServerId());
Long serverId = jobRequest.getGpuServerId();
// server의 상태체크 로직이 필요
Job job = jobRequest.toEntity(findBoardByServerId(serverId), findMemberById(memberId));
jobRepository.save(job);
return job.getId();
}
GET /api/labs/1/jobs/1 HTTP/1.1
Hibernate:
select
administra0_.id as col_0_0_
from
administrator administra0_
where
administra0_.email=? limit ?
Hibernate:
select
member0_.id as id1_5_,
member0_.created_at as created_2_5_,
member0_.updated_at as updated_3_5_,
member0_.email as email4_5_,
member0_.lab_id as lab_id8_5_,
member0_.member_type as member_t5_5_,
member0_.name as name6_5_,
member0_.password as password7_5_
from
member member0_
where
member0_.email=?
Hibernate:
select
lab0_.id as id1_4_0_,
lab0_.created_at as created_2_4_0_,
lab0_.updated_at as updated_3_4_0_,
lab0_.name as name4_4_0_
from
lab lab0_
where
lab0_.id=?
Hibernate:
select
member0_.id as id1_5_,
member0_.created_at as created_2_5_,
member0_.updated_at as updated_3_5_,
member0_.email as email4_5_,
member0_.lab_id as lab_id8_5_,
member0_.member_type as member_t5_5_,
member0_.name as name6_5_,
member0_.password as password7_5_
from
member member0_
where
member0_.email=?
Hibernate:
select
lab0_.id as id1_4_0_,
lab0_.created_at as created_2_4_0_,
lab0_.updated_at as updated_3_4_0_,
lab0_.name as name4_4_0_
from
lab lab0_
where
lab0_.id=?
Hibernate:
select
member0_.id as id1_5_0_,
member0_.created_at as created_2_5_0_,
member0_.updated_at as updated_3_5_0_,
member0_.email as email4_5_0_,
member0_.lab_id as lab_id8_5_0_,
member0_.member_type as member_t5_5_0_,
member0_.name as name6_5_0_,
member0_.password as password7_5_0_,
lab1_.id as id1_4_1_,
lab1_.created_at as created_2_4_1_,
lab1_.updated_at as updated_3_4_1_,
lab1_.name as name4_4_1_
from
member member0_
left outer join
lab lab1_
on member0_.lab_id=lab1_.id
where
member0_.id=?
Hibernate:
select
job0_.id as id1_3_0_,
job0_.created_at as created_2_3_0_,
job0_.updated_at as updated_3_3_0_,
job0_.completed_time as complete4_3_0_,
job0_.expected_time as expected5_3_0_,
job0_.gpu_board_id as gpu_boa10_3_0_,
job0_.member_id as member_11_3_0_,
job0_.meta_data as meta_dat6_3_0_,
job0_.name as name7_3_0_,
job0_.started_time as started_8_3_0_,
job0_.status as status9_3_0_,
gpuboard1_.id as id1_1_1_,
gpuboard1_.created_at as created_2_1_1_,
gpuboard1_.updated_at as updated_3_1_1_,
gpuboard1_.gpu_server_id as gpu_serv7_1_1_,
gpuboard1_.is_working as is_worki4_1_1_,
gpuboard1_.model_name as model_na5_1_1_,
gpuboard1_.performance as performa6_1_1_,
gpuserver2_.id as id1_2_2_,
gpuserver2_.created_at as created_2_2_2_,
gpuserver2_.updated_at as updated_3_2_2_,
gpuserver2_.disk_size as disk_siz4_2_2_,
gpuserver2_.is_on as is_on5_2_2_,
gpuserver2_.lab_id as lab_id9_2_2_,
gpuserver2_.last_response as last_res6_2_2_,
gpuserver2_.memory_size as memory_s7_2_2_,
gpuserver2_.name as name8_2_2_,
lab3_.id as id1_4_3_,
lab3_.created_at as created_2_4_3_,
lab3_.updated_at as updated_3_4_3_,
lab3_.name as name4_4_3_,
member4_.id as id1_5_4_,
member4_.created_at as created_2_5_4_,
member4_.updated_at as updated_3_5_4_,
member4_.email as email4_5_4_,
member4_.lab_id as lab_id8_5_4_,
member4_.member_type as member_t5_5_4_,
member4_.name as name6_5_4_,
member4_.password as password7_5_4_,
lab5_.id as id1_4_5_,
lab5_.created_at as created_2_4_5_,
lab5_.updated_at as updated_3_4_5_,
lab5_.name as name4_4_5_
from
job job0_
left outer join
gpu_board gpuboard1_
on job0_.gpu_board_id=gpuboard1_.id
left outer join
gpu_server gpuserver2_
on gpuboard1_.gpu_server_id=gpuserver2_.id
left outer join
lab lab3_
on gpuserver2_.lab_id=lab3_.id
left outer join
member member4_
on job0_.member_id=member4_.id
left outer join
lab lab5_
on member4_.lab_id=lab5_.id
where
job0_.id=?
field가 많아짐에 따라, getter/setter, null 체크 로직이 많아지기 때문에, 도메인 로직을 확인하기 어려움 존재
고민하는 문제
- Controller에서 Member객체를 굳이 받아야 할까?, memberId만 받아도 충분하지 않을까? -> 컨트롤러에서 member의 종류에 따라서 보여주는 로직이 달라지는 경우는 유용하겠지만, 지금의 우리 서비스에서 member객체를 바로 쓴느 경우는 드문 것으로 보인다.
- CUD작업에서는 검증이 필요하겠지만, 조회 로직에서도 서비스 단에 검증로직을 추가해야 할까?
- Enum으로 관리하는 Exception은 확장에 취약한 것으로 보임. (동일한 로직이 별도의 서비스에서 동시에 정의되어 있고, 각각 다른 에러메시지를 내보내는 부분을 통일시켜주기 위해 Enum을 도입했지만, 공통 로직을 도메인 단으로 옮겨왔을 때, 문제가 해결될 수 도 있을 거라 생각)
모든 Job관련 서비스가 GpuServer.isOn=false
인 경우 정상적으로 등록할 수 있게끔 테스트 코드가 짜여 있었음.
RestAssured에서는 우선 Worker측에서 Gpu상대 변경을 진행한 후 테스트를 진행하도록 수정
JobStatus.Waiting이 기본 상태가 아니라, 예약을 하는 시점에서 상태를 정해지도록 수정 (생성시 null) -> 테스트 코드의 많은 수정 필요. 객체를 생성하는 시점이 아닌 예약이 가능한 상황인지 검증이 이루어지고 나서야 예약상태로 변경되어야 된다고 판단.
@DisplayName("사용자의 Job 접근 권한을 확인한다.")
class CheckPermissionOnJob {
이 테스트는 도메인에서의 검증으로 대체
Entity의 equals(), hashcode() 의 구현은 그 의미가 퇴색됨. 영속성 컨텍스트에서 관리되는 객체들은 reference로 같음을 제공하기 때문에, id만을 equals의 기준으로 삼는 지금의 구현은 테스트 코드의 복잡성만을 야기한다고 판단.
DB 제약 조건 이름 명시적으로 알아볼 수 있도록 수정하면 좋을듯!