fix(redis): fix logs being polluted when redis is disabled

also used streaming when redis is disabled for faster response.
This commit is contained in:
zyachel
2022-11-13 17:29:47 +05:30
parent 6f664d2164
commit 5fd0d92187
7 changed files with 148 additions and 73 deletions

View File

@ -1,16 +1,16 @@
import Image from 'next/future/image'
import Link from 'next/link'
import { NextRouter } from 'next/router'
import { Media } from '../../interfaces/shared/title'
import { getProxiedIMDbImgUrl, modifyIMDbImg } from '../../utils/helpers'
import Image from 'next/future/image';
import Link from 'next/link';
import { NextRouter } from 'next/router';
import { Media } from '../../interfaces/shared/title';
import { getProxiedIMDbImgUrl, modifyIMDbImg } from '../../utils/helpers';
import styles from '../../styles/modules/components/title/media.module.scss'
import styles from '../../styles/modules/components/title/media.module.scss';
type Props = {
className: string
media: Media
router: NextRouter
}
className: string;
media: Media;
router: NextRouter;
};
const Media = ({ className, media, router }: Props) => {
return (
@ -32,8 +32,9 @@ const Media = ({ className, media, router }: Props) => {
modifyIMDbImg(media.trailer.thumbnail)
)}
className={styles.trailer__video}
preload="none"
>
{media.trailer.urls.map((source) => (
{media.trailer.urls.map(source => (
<source
key={source.url}
type={source.mimeType}
@ -46,7 +47,7 @@ const Media = ({ className, media, router }: Props) => {
)}
{!!media.videos.total &&
media.videos.videos.map((video) => (
media.videos.videos.map(video => (
<Link href={`/video/${video.id}`} key={video.id}>
<a className={styles.video}>
<Image
@ -69,7 +70,7 @@ const Media = ({ className, media, router }: Props) => {
<section className={styles.images}>
<h2 className="heading heading__secondary">Images</h2>
<div className={styles.images__container}>
{media.images.images.map((image) => (
{media.images.images.map(image => (
<figure key={image.id} className={styles.image}>
<Image
className={styles.image__img}
@ -87,6 +88,6 @@ const Media = ({ className, media, router }: Props) => {
</section>
)}
</div>
)
}
export default Media
);
};
export default Media;

View File

@ -1,59 +1,71 @@
import { NextApiRequest, NextApiResponse } from 'next'
import redis from '../../utils/redis'
import axiosInstance from '../../utils/axiosInstance'
import { AxiosResponse } from 'axios'
import { NextApiRequest, NextApiResponse } from 'next';
import redis from '../../utils/redis';
import axiosInstance from '../../utils/axiosInstance';
const regex =
/^https:\/\/((m\.)?media-amazon\.com|imdb-video\.media-imdb\.com).*\.(jpg|jpeg|png|mp4|gif|webp).*$/
/^https:\/\/((m\.)?media-amazon\.com|imdb-video\.media-imdb\.com).*\.(jpg|jpeg|png|mp4|gif|webp).*$/;
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const mediaUrl = req.query.url as string | undefined
try {
const mediaUrl = req.query.url as string | undefined;
if (!mediaUrl || !regex.test(mediaUrl))
return res.status(400).json({
success: false,
message: 'Invalid query',
})
// 1. returning if query is illegal
if (!mediaUrl || !regex.test(mediaUrl))
return res.status(400).json({
success: false,
message: 'Invalid query',
});
if (process.env.USE_REDIS === 'true') {
const cachedMedia = await redis.getBuffer(mediaUrl)
// 2. sending streamed response if redis isn't enabled
if (redis === null) {
const mediaRes = await axiosInstance.get(mediaUrl, {
responseType: 'stream',
});
res.setHeader('Content-Type', mediaRes.headers['content-type']);
mediaRes.data.pipe(res);
return;
}
// 3. else if resourced is cached, sending it
const cachedMedia = await redis!.getBuffer(mediaUrl);
if (cachedMedia) {
res.setHeader('x-cached', 'true')
res.status(302).send(cachedMedia)
return
res.setHeader('x-cached', 'true');
res.status(302).send(cachedMedia);
return;
}
}
let mediaRes: AxiosResponse
try {
mediaRes = await axiosInstance(mediaUrl, { responseType: 'arraybuffer' })
// 4. else getting, caching and sending response
const mediaRes = await axiosInstance(mediaUrl, {
responseType: 'arraybuffer',
});
const data = mediaRes.data;
// saving in redis for 30 minutes
await redis!.setex(mediaUrl, 30 * 60, Buffer.from(data));
// sending media
res.setHeader('x-cached', 'false');
res.send(data);
// sending token response on any error
} catch {
res.status(404)
res.status(404);
res.json({
success: false,
message: 'Error from IMDb',
})
return
message: 'something went wrong',
});
return;
}
const data = mediaRes.data
if (process.env.USE_REDIS === 'true') {
// save in redis for 30 minutes
await redis.setex(mediaUrl, 30 * 60, Buffer.from(data))
}
// send media
res.setHeader('x-cached', 'false')
res.send(data)
}
export const config = {
api: {
responseLimit: false,
},
}
};

View File

@ -1,11 +1,11 @@
import Redis from 'ioredis'
import Redis from 'ioredis';
const redisUrl = process.env.REDIS_URL
const redisUrl = process.env.REDIS_URL;
const toUseRedis = process.env.USE_REDIS === 'true';
if (!redisUrl) {
throw 'Please set the REDIS_URL environment variable.'
}
let redis: Redis | null;
const redis = new Redis(redisUrl)
if (toUseRedis && redisUrl) redis = new Redis(redisUrl);
else redis = null;
export default redis
export default redis;