본문 바로가기
React TIL

[React] Day_77 최종 프로젝트 관련 내용정리

by 림졍 2025. 1. 8.
반응형

 

다음 TIL 스포

 

기능 구현이랑 오늘도 싸우고 온 림졍..

그래도 새롭게 넣어주어야 할 기능들에 대한 공부는 얼추 완료했다(?)!

이제.. 이쁘게 만들면 되겠지..? @.@;;;

오늘은 어제에 이은 일지를 적는 것으로 TIL을 적어보겠습니다.

가시죠오오.

 

 

Supabase - Scheduling 기능, Next.js에서 활용 가능 여부 테스트 일지 - (2)

와아- 고봉밥급 뜨라블 슈띵!!!

 

우웁.. 배불러요...

 

테스트 과정 (이어서)

3. 스케쥴링 기능 추가해보기

 

스케쥴링 동작 방식

  1. calculate_fever_rooms 함수는 채팅방 메시지를 3시간 동안 집계합니다.
  2. 매일 오후 2시와 6시에 자동으로 실행됩니다.
  3. fever_time_rooms 테이블에 상위 5개 채팅방이 기록됩니다.

- fever time 스케쥴링 SQL

-- 1. 스케쥴링 함수 생성
CREATE OR REPLACE FUNCTION calculate_fever_rooms()
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
  -- 기존 피버타임 레코드 삭제
  DELETE FROM fever_time_rooms
  WHERE created_at::date = CURRENT_DATE;

  -- 가장 많이 메시지가 등록된 상위 5개의 채팅방 추출
  INSERT INTO fever_time_rooms (room_id, chat_per_hour, created_at)
  SELECT
    room_id,
    COUNT(*) AS chat_per_hour,
    now() AS created_at
  FROM messages
  WHERE created_at >= now() - interval '3 hours'  -- 최근 3시간 집계
  GROUP BY room_id
  ORDER BY chat_per_hour DESC
  LIMIT 5;
END;
$$;

-- 2. 스케쥴링 (하루 2번 실행)
SELECT cron.schedule(
  'fever_time_task',                      -- 작업명
  '0 14,18 * * *',                        -- 매일 오후 2시, 6시
  $$ CALL calculate_fever_rooms() $$      -- 함수 호출
);
  • 스케쥴링 함수 - 특정 시간(오후 2시, 6시)에 채팅 수를 집계 → 상위 5개 방을 fever_time 테이블에 저장
  • 삭제 및 업데이트 - 같은 날짜에 이미 저장된 데이터는 삭제 후 업데이트됨
  • cron.schedule - cron 사용하여 스케쥴링을 등록

 

cron 관련 뜨라블슈팅(?) - 부제 : 확장 설치의 중요성

 

문제 상황

 

왜... 왜 오류가 나는건데?

 

SQL 에디터에서 바로 Run 했더니..

[ ERROR: 3F000: schema "cron" does not exist ] 라는 에러가 뜨게 되었다..!!

아니 나는 SQL 모르는디.. 이러면.. 곤란해.. ㅠㅡㅠ

 

원인을 알고보니, Supabase PostgreSQL에 pg_cron 확장이 활성화되어 있지 않아서였다고..

따라서 cron 스키마는 pg_cron이라는 확장 프로그램을 설치해야 사용이 가능하다!

 

 

해결 방법: pg_cron 확장 활성화

 

Supabase에서 pg_cron을 사용하려면, 다음과 같이 확장설치 및 활성화를 시켜줘야 한다!

 

1. pg_cron 확장 설치

CREATE EXTENSION IF NOT EXISTS pg_cron;

 

2. cron 스키마 사용하도록 설정

SET search_path TO pg_catalog, public, cron;

 

일단 해당 내용이 나오는 것 까지 볼 수 있었음!!

 

트러블탕탕 하나 완! ^-^)b!

 

4. 튜터님에게 컨펌

  • test → 1분-2분 당 확인할 수 있게끔 채팅방 메시지를 임의로 추가
  • 실제로 계산이 되어서 적용이 되는지에 대한 여부 파악 필요 ^-^)b
  • 되면 2/6시로 변경하도록 Ok!

 

5. 채팅방 기본기능 추가 및 스케쥴링 잘 작동하는지 체킹하기

 

삭제기능이랑 추가기능, 미리보기를 통해 볼 수 있게끔 구현! (좌) 채팅방 이름을 띄우고, 업로드는 정상적으로 되는 것을 확인 (우)

 

 

6. 스케쥴링 테스트 SQL 작성 및 실행

 

 

테스트를 위해 1~2분 간격으로 calculate_fever_rooms 함수를 실행하는 SQL 작성

 

흐름 설명

  • 1분 간격으로 스케줄링 - * * * * * 설정으로 매분마다 실행
  • 실행 로그 확인 - cron.job_run_details에서 실행 결과 및 오류 여부 확인
  • 결과 데이터 확인 - fever_time_rooms 테이블에서 최근 추가된 레코드 확인 → 작동 확인여부 파악

 

1. 기존 스케줄 삭제 (테스트 중복 방지)

SELECT cron.unschedule('fever_time_task_test');

 

2. 1분 간격 테스트 스케줄링

SELECT cron.schedule(
  'fever_time_task_test',                  -- 테스트용 작업명
  '* * * * *',                             -- 매분 실행
  $$ CALL calculate_fever_rooms() $$       -- 함수 호출
);

 

3. 최근 스케줄 실행 내역 확인 (로그 확인)

SELECT * 
FROM cron.job_run_details 
WHERE jobid = (SELECT jobid FROM cron.job WHERE jobname = 'fever_time_task_test')
ORDER BY start_time DESC;

 

4. 결과 확인 (fever_time_rooms 테이블 데이터)

SELECT *
FROM fever_time_rooms
ORDER BY created_at DESC;

 

테스트 후 정리 (삭제 코드)

SELECT cron.unschedule('fever_time_task_test');

 

 

 

뜨라블슈팅(?) - Supabase 스케쥴링, calculate_fever_rooms() 호출 문제

 

해당 SQL의 결과는..?

ㅎㅎ 놀랍게도 Fail! (하긴 한번에 성공하는 림졍은 아니지 ^-^;;)

 

문제 상황

  • 채팅방의 Fever-time을 기록하기 위한 스케줄링 SQL을 작성했는데, 예상치 못한 에러 발생!
  • 매일 오후 2시, 6시에 채팅방 메시지를 집계해 상위 5개 방을 fever_time_rooms 테이블에 저장하는 기능이 목표였음..!

- SQL 코드 (최초 버전)

-- 1. Fever-time 집계 함수 생성
CREATE OR REPLACE FUNCTION calculate_fever_rooms()
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
  -- 기존 fever_time_rooms 데이터 삭제 (오늘자)
  DELETE FROM fever_time_rooms
  WHERE created_at::date = CURRENT_DATE;

  -- 최근 3시간 동안 메시지가 가장 많은 상위 5개 채팅방 추출
  INSERT INTO fever_time_rooms (room_id, rank_or_hourly_chats, created_at)
  SELECT
    room_id,
    COUNT(*) AS rank_or_hourly_chats,
    now() AS created_at
  FROM messages
  WHERE created_at >= now() - interval '3 hours'
  GROUP BY room_id
  ORDER BY rank_or_hourly_chats DESC
  LIMIT 5;
END;
$$;

-- 2. 스케줄링 (매일 오후 2시, 6시 실행)
SELECT cron.schedule(
  'fever_time_task',
  '0 14,18 * * *',
  $$ CALL calculate_fever_rooms() $$  -- 이 부분에서 에러 발생
);

 

원인분석

ERROR: calculate_fever_rooms() is not a procedure  
HINT: To call a function, use SELECT.

 

  • CALL 구문은 stored procedure를 호출하는 방식인데, calculate_fever_rooms는 FUNCTION으로 정의됨
  • PostgreSQL에서 Function을 호출할 때는 CALL이 아니라 SELECT를 사용해야 함

 

해결 과정

 

1. 기존 스케줄 삭제 (잘못된 스케줄 제거)

SELECT cron.unschedule('fever_time_task_test');

 

2. CALL → SELECT로 수정한 스케줄 다시 등록

-- 수정된 스케줄 등록 (SELECT 사용)
SELECT cron.schedule(
  'fever_time_task_test',
  '* * * * *',  -- 매분 테스트
  $$ SELECT calculate_fever_rooms() $$  -- 함수 호출 방식 수정
);

 

3. 실행 내역 및 결과 데이터 확인

-- 최근 실행 로그 확인
SELECT * 
FROM cron.job_run_details
ORDER BY start_time DESC;

-- fever_time_rooms 테이블에서 데이터 확인
SELECT * 
FROM fever_time_rooms
ORDER BY created_at DESC;

 

 

다시 생각해보는 원인.. (근데 백엔드 지식이라 솔직히 모르겠음..)

 

1. 왜 CALL이 안될까?

  • CALL은 stored procedure 전용 → Function은 SELECT로 호출하기
  •  PostgreSQL에서는 CREATE FUNCTION과 CREATE PROCEDURE가 다르게 동작함
  • Function 호출: SELECT 사용
  • Procedure 호출: CALL 사용

- 차이점 비교

-- Function 호출 방식
SELECT my_function();

-- Procedure 호출 방식
CALL my_procedure();

 

2. 왜 stored procedure를 사용하지 않았을까?

  • Supabase의 스케줄링에서는 보통 Function을 사용해 데이터를 처리함.
  • Procedure는 트랜잭션 및 복잡한 비즈니스 로직에서 주로 사용되며, 단순 집계에는 Function이 더 적합함.

 

 

결과

 

잘 가져와지는 것을 확인 할 수 있음!!! ^-^)b!!

 

 

 

알게된 점 (기억하자!)

  • CALL 구문은 Procedure를 호출할 때 사용.. ( calculate_fever_rooms, Function으로 정의)
  • PostgreSQL에서는 Function을 호출할 때 SELECT 구문을 사용 → SELECT로 변경해주기

 

- 수정된 테스트 스케줄링 (1~2분 간격) SQL

-- 1분 간격으로 테스트
SELECT cron.schedule(
  'fever_time_task_test',
  '* * * * *',
  $$ SELECT calculate_fever_rooms() $$
);

-- 실행 결과 확인
SELECT * FROM cron.job_run_details
ORDER BY start_time DESC;

-- 데이터 확인
SELECT * FROM fever_time_rooms
ORDER BY created_at DESC;

 

- 최종 수정된 스케쥴링 SQL

-- 1. 스케쥴링 함수 생성 (수정 없음)
CREATE OR REPLACE FUNCTION calculate_fever_rooms()
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
  -- 기존 피버타임 레코드 삭제
  DELETE FROM fever_time_rooms
  WHERE created_at::date = CURRENT_DATE;

  -- 가장 많이 메시지가 등록된 상위 5개의 채팅방 추출
  INSERT INTO fever_time_rooms (room_id, chat_per_hour, created_at)
  SELECT
    room_id,
    COUNT(*) AS chat_per_hour,
    now() AS created_at
  FROM messages
  WHERE created_at >= now() - interval '3 hours'  -- 최근 3시간 집계
  GROUP BY room_id
  ORDER BY chat_per_hour DESC
  LIMIT 5;
END;
$$;

-- 2. 스케쥴링 (하루 2번 실행)
SELECT cron.schedule(
  'fever_time_task',                      -- 작업명
  '0 14,18 * * *',                        -- 매일 오후 2시, 6시
  $$ SELECT calculate_fever_rooms() $$    -- 함수 호출 (SELECT 사용)
);

 

 

 

 

마무리 -  정리는 꾸준하게!

 

편-안

 

 

5분기록보드를 사용해서 정리를 하는 중인데..

처음엔 이걸 왜 써.. 이러고 있었지만?

진행 업무 파악도 편리하고 적어놓고 나중에 꺼내보기에 유용해서 매우 알차게 쓰는중 🥹!!

히히 기능 공부도 완료되었으니 내일은 기능구현.. 들어가야겠지? ㅠㅡㅠ

몸이 쑤신다. 자러가야지 😴...

 

 

 

오늘의 KPT 회고

 

Keep: 5분기록보드 매일매일 열심히 쓰는 습관 아주 좋아요 ^-^)b!

Problem: 너무 열심히 정리하다보니 끝은 항상 용두사미가 되는 림졍이라 걱정중

Try: 열심히 정리하기!

728x90
반응형