8월 24일 TIL

·2023년 8월 24일
0

CS공부

▶ 스케쥴링

CS핵심용어 간단 정리
프로세스란? 프로그램을 실행하는 주체
쓰레드란? 작업을 처리하는 주체

OS는 시스템 성능을 끌어올리기 위해 어떻게 해야하는가?
실행 대기 중인 프로그램들에게 적절한 CPU 자원 배정
공통 배정 조건 : 오버헤드↓ / 사용률 ↑ / 기아 현상 ↓

▷ 스케쥴링 단위
CPU Burst : 프로그램 사용중 연속적으로 CPU를 사용하는 구간
I/O Burst : 입력 대기, 출력 대기 상태. I/O작업이 끝날 때까지 Block

▷ 스케쥴링 알고리즘 평가기준
1. CPU이용률 - 전체 중 CPU의 작업 처리 시간 비율
2. 처리량 : CPU의 단위 시간당 처리하는 프로세스 개
3. 총 처리 시간: 프로세스가 시작해서 끝날 때까지 시간
4. 대기 시간 : 준비완료 큐에서 대기하는 시간의 총 합
5. 응답 시간 : 대화식 시스템에서 요청 후 첫 응답이 오기까지 시간

▷ 스케쥴링 종류
· 선점 스케쥴링
OS가 CPU 사용권 선점, 특정 요건에 맞게 각 프로세스의 요청이 있을 때 분배
가장 자원이 필요한 프로세스에게 분배하고 상황에 따라 강제 회수 가능 / 양보 강요 가능
대화식 시분할 시스템에 적합, 긴급 프로세스 제어 가능
선점스케쥴링 종류
1. 우선순위 스케쥴링(정적/동적) - Aging 방법으로 기아현상 문제 해결, 우선 순위 같다면 FCFS 적용
2. 라운드로빈 - FCFS로 프로세스들이 보내지면 동일한 시간 범위 만큼 CPU할당, 다 못했으면 다시 뒤로가서 차례 기다림(회전식), 문맥 전환이 많이 발생된다.
3. 다단계큐 - 준비완료 큐를 여러 개로 분리 후 각각 다른 스케쥴링 알고리즘 방식 사용,

· 비선점 스케쥴링
프로세스가 CPU를 할당받으면 프로세스 종류 또는 입출력 요구 등의 이유로 자발적 중지가 될 때까지 계속 실행 보장
순서대로 처리(공정), 문맥교환에 의한 오버헤드 적음
대기 시간이 길어져서 처리율이 떨어질 수 있음
비선점스케쥴링 종류
1. FCFS - 큐 도착 순서대로 CPU 할당, FIFO큐 이용(먼저 입력 먼저 처리), Convoy Effect(호위효과, 순서를 기다려야하는 대기시간)
2. SJF - 수행시간 짧다고 판단되는 것 먼저 수행 = 대기시간 감소, 짧은 작업에 좋음
3. HRN - 우선순위 계산, 점유 불평등 보완, 수행시간 짧다고 먼저 실행하지 않음
→ 우선순위 = (대기시간+실행시간) / 실행시간

▷ 스케쥴링 동작 시점
스케쥴링 알고리즘에 따라서 프로세스의 상태 변화가 일어나고 준비 또는 수행 상태일 때 CPU를 사용한다.
비선점 스케쥴링 - 프로세스 스스로 CPU 반환
· 수행 → 대기 : I/O 요청 발생, 자식 프로세스 종료 대기
· 수행 → 종료 : 프로세스 종료
선점 스케쥴링 - 프로세스에서 CPU를 강제로 할당(회수)
· 수행 → 준비 : 인터럽트(중단) 발생

· 대기 → 준비 : I/O 완료

최종 프로젝트 진행 중..

현재 1차적으로 내가 맡은 프리랜서 마켓에 대한 부분이 마무리 되어서 내가 할 수 있는 선에서 리팩토링을 진행하게 되었다! 그 중 부분적인 내용을 작성할 것이다.

// api/Project.ts 프로젝트에 관한 통신에 대한 함수를 모아놓은 파일
// 기존에 사용한 getProjects 함수
export const getProjects = async (): Promise<Project[]> => {
  const { data: projects } = await supabase
    .from("projects")
    .select("*")
    .order("created_at", { ascending: true });
  return projects as Project[];
};

// 컴포넌트 내부에서 useQuery로 getProjects 함수 사용 부분
  const {
    data: projectLists,
    isLoading: projectListsIsLoading,
    isError: projectListsIsError,
    refetch: refetchProjectLists,
  } = useQuery(["currentClientprojectLists", freelancerItem.userId], () => getProjects(), {
    enabled: !!userId,
    select: (projectLists) =>
      projectLists?.filter(
        (projectList) =>
          projectList.clientId === userId &&
          projectList.status === "진행 전" &&
          !projectList.SuggestedFreelancers?.includes(freelancerItem.userId)
      ),
  });

이 부분을 수정할건데 간단히 설명하자면
useQuery를 사용해서 data값을 불러오는데 현재 2번째 인자로 사용되는 함수인 getProjects는 모든 db에 저장된 project값을 전부 불러와서 select 옵션을 이용해서 필터링 후 내가 원하는 값으로 가공?하는 식으로 작성되어있다.
하지만 현재 내배캠 튜터님께 피드백을 받은 결과 우리는 서버 쪽과 통신을 할 때 비용을 최소화 할 줄 알아야하는데 이런식으로 작성되면 코드는 깔끔해지겠지만 내가 원하는 project값 뿐만이 아닌 전체 project값이 이미 가져와지기 때문에 쓰지 않는 값들에 대한 비용까지 발생한다는 점을 알게 되었다.

getProjects를 대체할 함수를 새롭게 작성하였다.
일단 이 곳에서 기존 select 옵션 내부에 있는 filter와 비슷하게 data를 걸러보았다.

export const getPublishedProjectsWithBeforeProgress = async (
  clientId: string
): Promise<Project[]> => {
  const { data: projects } = await supabase
    .from("projects")
    .select("*")
    .eq("clientId", clientId)
    .eq("status", "진행 전");
  return projects as Project[];
};

이렇게 가져올 때부터

projectList.clientId === userId &&
projectList.status === "진행 전" 

이 부분을 eq로 걸러내서 조금 더 필요한 데이터에 맞는 부분만 가져올 수 있었다.

!projectList.SuggestedFreelancers?.includes(freelancerItem.userId)

하지만 이 부분은 내가 아는 supabase의 메소드로는 대체되는 것이 없는 듯 했다.

그래서 2가지의 선택지가 생겼다.
(1) getPublishedProjectsWithBeforeProgress 함수 내부에서 가져온 data를 filter해서 return한다.

const { data: projects } = await supabase
    .from("projects")
    .select("*")
    .eq("clientId", clientId)
    .eq("status", status);

  const filteredProjects = projects.filter(project =>
    !project.SuggestedFreelancers?.includes(excludedUserId)
  );

  return filteredProjects as Project[];

(2) useQuery를 사용하면서 기존 select 방식을 사용하여 함수에서 return 된 값에 filter를 건다.

select: (projectLists) =>
        projectLists?.filter(
          (projectList) =>
            !projectList.SuggestedFreelancers?.includes(freelancerItem.userId)
        ),

사실 내가 보기엔 처음에 고려했던 비용 문제 등을 생각하면 이제는 두 경우 다 비슷한 것 같았다.

그래서 나는 filter를 위해서 새로운 변수에 값을 담고 그 변수를 return 해주는 경우보다는 가독성이 좋다고 느껴지는 2번을 선택해서 진행하였다.

이렇게 해서 해당 부분을 나름대로 리팩토링 해보았다!
잘 작동하는 것까지 확인 완료 ✔

profile
코린한별

0개의 댓글