I made a small MERN app where users can upload images, and I've used multer for that. While it works fine in development, after deploying to heroku, every time I try to upload an image I get an error with code=H12(Request timeout), and it says that the request took more than 3s to load. After some digging, I found that heroku has a time limit of 3000ms for a request to respond, before giving this error.
The only solution is to implement the image uploading as a background job, but I don't even know what to start with as I had never done this before.
What is the best way to implement the image uploading as a background job? Any suggestion or link to tutorial would be very helpful and appreciated.
The route file for image uploading:
const router = require('express').Router();
const multer = require('multer');
const FILE_PATH = 'uploads';
const { uploadPhoto } = require('../controllers/photos/upload-photo');
const storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, FILE_PATH),
filename: (req, file, cb) => {
cb(null, `${Date.now()}_${file.originalname}`)
},
fileFilter: (req, file, cb) => {
if (!file.originalname.match(/.(jpeg|jpg|png|JPG|PNG)$/)) {
console.log('Only upload jpg and png files.');
}
cb(undefined, true);
},
});
router.post('/upload/:userid', multer({ storage }).single('photo'), uploadPhoto);
module.exports = router;
The controller file for image upload:
const User = require('../../models/User');
const Photo = require('../../models/Photo');
exports.uploadPhoto = (req, res) => {
//My approach with Multer
const { file: { mimetype, filename, path }, protocol } = req;
const url = `${protocol}://${req.get('host')}`;
User
.findById(req.params.userid)
.exec((error, user) => {
if (error || !user) return res.status(404).json({ message: error.message, });
const newPhoto = new Photo({
photo: {
mimetype,
photoUrl: `${url}/${path}`,
name: filename,
},
owner: user._id,
});
newPhoto.save((error, photo) => {
if (error) {
return res.status(404).json({ message: error.message, });
}
user.photos.push(newPhoto._id);
user.save();
return res.status(201).json({
message: `Image created`,
photoUrl: photo.photoUrl,
});
});
});
};
question from:
https://stackoverflow.com/questions/65648356/what-is-the-best-approach-to-implement-a-background-job-in-a-mern-app