Skip to content

Commit

Permalink
fix: del redis at delete action, log css fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ptyoiy committed Apr 10, 2024
1 parent fb4c1dd commit 8aad58d
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 60 deletions.
40 changes: 19 additions & 21 deletions adminPage/components/css/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,25 @@ section[data-css="notices-show-priority"] {
background-color: unset!important;
}
}
section[data-css="app-content"] {
pre {
padding: 0;
word-wrap: break-word;
white-space: pre-wrap;
overflow-x: hidden;
overflow-y: auto;
}
.log-wrapper {
display: flex;
border: 1px solid lightgrey;
border-bottom: unset;
padding: 8px!important;
}
.log-wrapper:last-child {
border-bottom: 1px solid lightgrey;
}
.log-line {
overflow-wrap: anywhere;
white-space: normal;
}
.log-box {
padding: 0;
word-wrap: break-word;
white-space: pre-wrap;
overflow-x: hidden;
overflow-y: auto;
}
.log-wrapper {
display: flex;
border: 1px solid lightgrey;
border-bottom: unset;
padding: 8px!important;
}
.log-wrapper:last-child {
border-bottom: 1px solid lightgrey;
}
.log-line {
overflow-wrap: anywhere;
white-space: normal;
}
section.login__Wrapper {
.adminjs_Text {
Expand Down
4 changes: 2 additions & 2 deletions adminPage/components/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from "@adminjs/design-system";
import { styled } from "@adminjs/design-system/styled-components";
import { useCurrentAdmin, useTranslation } from "adminjs";
import React, {useEffect, useRef} from "react";
import React, { useEffect, useRef } from "react";
import { useNavigate } from "react-router";
import { useLog } from "./hook";
type BoxType = {
Expand Down Expand Up @@ -148,7 +148,7 @@ export const Dashboard = (props) => {
<Card>
<Text textAlign="left">
Log
<Text ref={logRef} as="pre" height={400}>
<Text ref={logRef} as="pre" height={400} className="log-box">
{lines.map((line, index) => {
// 라인 번호 포맷팅: 번호를 문자열로 변환하고, 필요한 만큼 공백으로 채움
const lineNumber = `${index + 1}`.padEnd(maxLineNumberLength, ' ');
Expand Down
35 changes: 31 additions & 4 deletions adminPage/handlers/notice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { ActionHandler, Filter, SortSetter, flat, populator } from "adminjs";
import { Op } from "sequelize";
import Notice from "../../models/notice.js";
import { INotice } from "../../models/types.js";
import { cachingAllNotices } from "../../redis/caching.js";
import { redisClient } from "../../redis/connect.js";
import { setNoticeSchedule } from "../../redis/schedule.js";
import { delNoticeSchedule, setNoticeSchedule } from "../../redis/schedule.js";
import { NoticeActionQueryParameters } from "./index.js";

const list: ActionHandler<any> = async (request, response, context) => {
Expand Down Expand Up @@ -76,12 +77,12 @@ const list: ActionHandler<any> = async (request, response, context) => {
*/
const after = (action: 'edit' | 'new') => async (originalResponse, request, context) => {
const isPost = request.method === 'post';
const isEdit = context.action.name === action;
const isAction = context.action.name === action;
const {currentAdmin: {role}} = context;
const hasRecord = originalResponse?.record?.params;
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)) {
if ((isPost && isAction) && (hasRecord && !hasError)) {
// 학과는 로그인한 관리자의 것으로 적용
if (role != '관리자') {
hasRecord.major_advisor = role;
Expand Down Expand Up @@ -115,7 +116,33 @@ const after = (action: 'edit' | 'new') => async (originalResponse, request, cont
return originalResponse
}

// delete -> 삭제 후 redis 업데이트(개별 공지 제거, 전체 공지 업데이트)
const deleteAfter = () => async (originalResponse, request, context) => {
const isPost = request.method === 'post';
const isAction = context.action.name === 'delete';
const hasRecord = originalResponse?.record?.params;
const hasError = Object.keys(originalResponse.record.errors).length;
// checking if object doesn't have any errors or is a edit action
if ((isPost && isAction) && (hasRecord && !hasError)) {
const {priority, id} = hasRecord;
const isGeneral = priority == '일반'
const redisKeyEach = `notice:${id}`;

// 해당 글의 캐싱데이터 제거
await redisClient.del(redisKeyEach);
// 긴급일 경우 스케쥴에서 제거
if (!isGeneral) {
delNoticeSchedule(hasRecord);
}
// 전체 목록 캐싱
await cachingAllNotices();
}

return originalResponse
}

export const NoticeHandler = {
list,
after
after,
deleteAfter
}
5 changes: 4 additions & 1 deletion adminPage/resources/notice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ const noticeOptions: ResourceOptions = {
new: {
after: NoticeHandler.after('new'),
component: Components.notice_edit
},
delete: {
after: NoticeHandler.deleteAfter()
}
}
}
Expand All @@ -56,7 +59,7 @@ const noticeFeatures = [uploadFeature({
// 저장할 파일의 각종 정보들을 테이블의 어떤 속성에 저장할 지 설정
properties: {
key: "image", // 저장된 경로를 image 속성에 저장
}
},
})];

export const NOTICE = {
Expand Down
53 changes: 34 additions & 19 deletions redis/caching.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Op } from "sequelize";
import Event from "../models/events.js";
import Notice from "../models/notice.js";
import { IEvent, INotice } from "../models/types.js";
Expand Down Expand Up @@ -39,38 +38,54 @@ export const initAllOngoingEvents = async () => {
** 전체 공지글 redisKey - 일반 ? alerts:general : alerts:urgent
** 개별 공지글 redisKey - notice:id
*/
export const initAllOngoingNotices = async (priority: "일반" | "긴급") => {
const isGeneral = priority == "일반";
const redisKey = `alerts:${isGeneral ? "general" : "urgent"}`;
export const initAllOngoingNotices = async () => {
const currentDate = new Date();
const eachNotices = await redisClient.keys(`notice:*`);
const noticesFromDB = await Notice.findAll({
where: {
expired: false, // 활성화된 공지만 가져오기
priority: {
[Op.eq]: priority,
},
},
});
// 개별 공지 캐싱
const [urgent, general] = await getAllNotices();
// 과거 캐싱 기록 제거
if (eachNotices.length) {
await redisClient.del(eachNotices);
eachNotices.splice(0, eachNotices.length);
}
for (const notice of noticesFromDB as INotice[]) {

for (const notice of urgent as INotice[]) {
const redisKey = `notice:${notice.id}`;
// 일반 공지로 이동해야할 긴급 공지가 있는지 체크
const noticeNextDay = getNextDay(new Date(notice.date));
if (!isGeneral && (noticeNextDay > currentDate.getTime())) {
if (noticeNextDay > currentDate.getTime()) {
setNoticeSchedule(notice);
eachNotices.push(redisKey);
} else {
notice.update({ ...notice, priority: "일반" })
}
// 개별 공지 캐싱
await redisClient.set(redisKey, JSON.stringify(notice));
}
// 전체 공지 캐싱
await redisClient.set(redisKey, JSON.stringify(noticesFromDB));

priority == "긴급" && console.log(`진행중인 공지: `, eachNotices);
for (const notice of general as INotice[]) {
const redisKey = `notice:${notice.id}`;
await redisClient.set(redisKey, JSON.stringify(notice));
}
await cachingAllNotices(urgent, general);
};

export const cachingAllNotices = async (urgent?, general?) => {
if (!urgent && !general) [urgent, general] = await getAllNotices();
await redisClient.set(`alerts:urgent`, JSON.stringify(urgent));
await redisClient.set(`alerts:general`, JSON.stringify(general));
}
/**
* @returns [urgent, general]
*/
const getAllNotices = async () => {
// 전체 긴급 공지 목록 캐싱
const [urgent, general] = (await Notice.findAll({
where: {
expired: false, // 활성화된 공지만 가져오기
}
})).reduce((acc, val: INotice) => {
acc[+(val.priority == '일반')].push(val);
return acc;
}, [[], []]);

return [urgent, general] as [INotice[], INotice[]];
}
3 changes: 1 addition & 2 deletions redis/initialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ import { connectRedis } from "./connect.js";
export const initializeRedis = async () => {
await connectRedis();
await initAllOngoingEvents();
await initAllOngoingNotices('일반');
await initAllOngoingNotices('긴급');
await initAllOngoingNotices();
}
25 changes: 14 additions & 11 deletions redis/schedule.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Job, scheduleJob } from "node-schedule";
import Notice from "../models/notice.js";
import { INotice } from "../models/types.js";
import { cachingAllNotices } from "./caching.js";
import { redisClient } from "./connect.js";

const jobArray: Job[] = [];
Expand All @@ -11,16 +11,7 @@ export const setNoticeSchedule = (row: INotice) => {
const updatedRow = await row.update({ ...row, priority: "일반" });
await redisClient.set(`notice:${id}`, JSON.stringify(updatedRow));
// 전체 긴급 공지 목록 캐싱
const [urgent, general] = (await Notice.findAll({
where: {
expired: false, // 활성화된 공지만 가져오기
}
})).reduce((acc, val: INotice) => {
acc[+(val.priority == '일반')].push(val);
return acc;
}, [[], []]);
await redisClient.set(`alerts:urgent`, JSON.stringify(urgent));
await redisClient.set(`alerts:general`, JSON.stringify(general));
await cachingAllNotices();
jobArray.splice(existJobIndex, 1);
});
const existJobIndex = jobArray.findIndex(j => j.name == `${id}`);
Expand All @@ -33,5 +24,17 @@ export const setNoticeSchedule = (row: INotice) => {
console.log('set schedule:', `${id}-${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}`);
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));
} else {
console.warn(`jobArray hasn't schedule-${id}`);
}
}

export const getNextDay = (date: Date) => date.setDate(date.getDate() + 1);

0 comments on commit 8aad58d

Please sign in to comment.