Skip to content

Commit

Permalink
feat: 행사 스케쥴러 등록/제거 기능
Browse files Browse the repository at this point in the history
  • Loading branch information
ptyoiy committed May 2, 2024
1 parent e88153f commit a2c1c49
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 31 deletions.
46 changes: 33 additions & 13 deletions adminPage/handlers/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { ActionHandler, Filter, SortSetter, flat, populator } from "adminjs";
import Event from "../../models/events.js";
import { redisClient } from "../../redis/connect.js";
import { EventActionQueryParameters } from "./index.js";
import { IEvent } from "../../models/types.js";
import { delEventSchedule, setEventSchedule } from "../../redis/schedule.js";

const list: ActionHandler<any> = async (request, response, context) => {
const { query } = request; // 요청 url의 query 부분 추출
Expand Down Expand Up @@ -85,15 +87,24 @@ const after = (action: "edit" | "new") => async (originalResponse, request, cont
const hasError = Object.keys(originalResponse.record.errors).length;
// checking if object doesn't have any errors or is a edit action
if (isPost && isEdit && hasRecord && !hasError) {
const {id, end} = hasRecord
// 학과는 로그인한 관리자의 것으로 적용
if (role != "관리자") {
hasRecord.major_advisor = role;
}
// redis 캐싱
const redisKeyEach = `event:${hasRecord.id}`;
const redisKeyEach = `event:${id}`;
const redisKeyAll = "allEvents";

await redisClient.set(redisKeyEach, JSON.stringify(hasRecord));
// end날이 아직 안 지났다면
if (end > new Date()) {
// 종료 변경하는 스케쥴 등록
console.log("has update::?",hasRecord.update);
const recordModel = (await Event.findOne({
where: {id}
})) as IEvent;
setEventSchedule(recordModel);
}
// 전체 목록 캐싱
const allEventsFromDb = await Event.findAll({
where: {
Expand All @@ -114,9 +125,14 @@ const deleteAfter = () => async (originalResponse, request, context) => {

// checking if object doesn't have any errors or is a edit action
if (isPost && isAction && record) {
await redisClient.del(`event:${record.id}`);

const {id, end} = record;
const redisKeyAll = "allEvents";

await redisClient.del(`event:${id}`);

if (end > new Date()) {
delEventSchedule(record);
}
// 전체 목록 캐싱
const allEventsFromDb = await Event.findAll({
where: {
Expand All @@ -140,17 +156,21 @@ const bulkDelete = () => async (originalResponse, request, context) => {
records.forEach(async ({params: record}) => {
// redis 캐싱 제거
await redisClient.del(`event:${record.id}`);
if (record.end > new Date()) {
// 스케쥴에 등록된 행사들 제거
delEventSchedule(record);
}
});
const redisKeyAll = "allEvents";
// 전체 목록 캐싱
const allEventsFromDb = await Event.findAll({
where: {
expired: false, // 진행중인 행사만 가져오기
},
order: [["start", "ASC"]],
});
await redisClient.set(redisKeyAll, JSON.stringify(allEventsFromDb));
}
const redisKeyAll = "allEvents";
// 전체 목록 캐싱
const allEventsFromDb = await Event.findAll({
where: {
expired: false, // 진행중인 행사만 가져오기
},
order: [["start", "ASC"]],
});
await redisClient.set(redisKeyAll, JSON.stringify(allEventsFromDb));
return originalResponse;
};

Expand Down
1 change: 0 additions & 1 deletion models/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,4 @@ const Event = sequelize.define<IEvent>(
timestamps: false, // createdAt 및 updatedAt 필드 생성 방지
}
);

export default Event
11 changes: 10 additions & 1 deletion redis/caching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Linktree from "../models/linktree.js";
import Notice from "../models/notice.js";
import { IEvent, INotice } from "../models/types.js";
import { redisClient } from "./connect.js";
import { getNextDay, setNoticeSchedule } from "./schedule.js";
import { getNextDay, setEventSchedule, setNoticeSchedule } from "./schedule.js";

export const initAllLinktrees = async () => {
const redisKey = "linktrees";
Expand Down Expand Up @@ -33,6 +33,7 @@ export const initAllLinktrees = async () => {
export const initAllOngoingEvents = async () => {
const redisKey = "allEvents";
const eachEvents = await redisClient.keys(`event:*`);
const currentDate = new Date();
const eventsFromDb = (await Event.findAll({
where: {
expired: false, // 진행중인 행사만 가져오기
Expand All @@ -48,6 +49,14 @@ export const initAllOngoingEvents = async () => {
}
for (const event of eventsFromDb) {
const eventRedisKey = `event:${event.id}`;
// 종료 전이면
if (event.end > currentDate) {
// 종료 날에 종료되도록 스케쥴링
setEventSchedule(event);
} else { // 종료 됐으면
// 종료로 변경
event.update({...event, expired: true});
}
await redisClient.set(eventRedisKey, JSON.stringify(event));
}

Expand Down
85 changes: 69 additions & 16 deletions redis/schedule.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,94 @@
import { Job, scheduleJob } from "node-schedule";
import { INotice } from "../models/types.js";
import { IEvent, INotice } from "../models/types.js";
import { cachingAllNotices } from "./caching.js";
import { redisClient } from "./connect.js";
import Event from "../models/events.js";

const jobArray: Job[] = [];
export const setNoticeSchedule = (row: INotice) => {
const { id, date } = row;
const job = scheduleJob(`${id}`, getNextDay(date), async function () {
console.log("run schedule:", id, date.toLocaleString(), "to 일반");
const key = `notice:${id}`;
const job = scheduleJob(key, getNextDay(date), async function () {
console.log("run schedule:", key, date.toLocaleString(), "to 일반");
const updatedRow = await row.update({ ...row, priority: "일반" });
await redisClient.set(`notice:${id}`, JSON.stringify(updatedRow));
await redisClient.set(key, JSON.stringify(updatedRow));
// 전체 긴급 공지 목록 캐싱
await cachingAllNotices();
jobArray.splice(existJobIndex, 1);
});
console.log({jobArray})
const existJobIndex = jobArray.findIndex(j => j?.name == `${id}`);
const existJobIndex = jobArray.findIndex((j) => j?.name == key);
if (existJobIndex > -1) {
jobArray[existJobIndex].cancel();
jobArray[existJobIndex] = job;
} else {
jobArray.push(job);
}
console.log('set schedule:', `${id}-${date.toLocaleString()}`);
console.log('job list:', jobArray.map(j => j?.name));
console.log("set schedule:", `${key}-${date.toLocaleString()}`);
console.log(
"job list:",
jobArray.map((j) => j?.name)
);
};
export const delNoticeSchedule = (row: INotice) => {
const {id, date} = row;
const existJobIndex = jobArray.findIndex(j => j.name == `${id}`);
const { id, date } = row;
const key = `notice:${id}`;
const existJobIndex = jobArray.findIndex((j) => j.name == `${key}`);
if (existJobIndex > -1) {
jobArray[existJobIndex].cancel();
jobArray.splice(existJobIndex, 1);
console.log('del schedule:', `${id}-${date.toLocaleString()}`);
console.log('job list:', jobArray.map(j => j?.name));
console.log("del schedule:", `${key}-${date.toLocaleString()}`);
console.log(
"job list:",
jobArray.map((j) => j?.name)
);
} else {
console.warn(`jobArray hasn't schedule-${id}`);
console.warn(`jobArray hasn't schedule-${key}`);
}
}

export const getNextDay = (date: Date) => date.setDate(date.getDate() + 1);
};
export const setEventSchedule = (row: IEvent) => {
const { id, end } = row;
const key = `event:${id}`;
const job = scheduleJob(key, end, async function () {
console.log("run schedule:", key, end.toLocaleString(), "to 행사 종료");
const updatedRow = await row.update({ ...row, expired: true });
await redisClient.set(key, JSON.stringify(updatedRow));
// 전체 행사 목록 캐싱
const allEventsFromDb = await Event.findAll({
where: {
expired: false, // 진행중인 행사만 가져오기
},
order: [["start", "ASC"]],
});
await redisClient.set("allEvents", JSON.stringify(allEventsFromDb));
jobArray.splice(existJobIndex, 1);
});
const existJobIndex = jobArray.findIndex((j) => j?.name == key);
if (existJobIndex > -1) {
jobArray[existJobIndex].cancel();
jobArray[existJobIndex] = job;
} else {
jobArray.push(job);
}
console.log("set schedule:", `${key}-${end.toLocaleString()}`);
console.log(
"job list:",
jobArray.map((j) => j?.name)
);
};
export const delEventSchedule = (row: IEvent) => {
const { id, end } = row;
const key = `event:${id}`;
const existJobIndex = jobArray.findIndex((j) => j.name == `${key}`);
if (existJobIndex > -1) {
jobArray[existJobIndex].cancel();
jobArray.splice(existJobIndex, 1);
console.log("del schedule:", `${key}-${end.toLocaleString()}`);
console.log(
"job list:",
jobArray.map((j) => j?.name)
);
} else {
console.warn(`jobArray hasn't schedule-${key}`);
}
};
export const getNextDay = (date: Date) => date.setDate(date.getDate() + 1);

0 comments on commit a2c1c49

Please sign in to comment.