-
-
Save isocroft/adf3263c2c3ff5d2119712ea6485f0c1 to your computer and use it in GitHub Desktop.
Show PostgreSQL current (running) process list;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SELECT user, pid, client_addr, waiting, query, query_start, NOW() - query_start AS elapsed | |
| FROM pg_stat_activity | |
| WHERE query != '<IDLE>' | |
| -- AND EXTRACT(EPOCH FROM (NOW() - query_start)) > 1 | |
| ORDER BY elapsed DESC; |
Author
// relay-server.js (Relayservice server)
const express = require('express');
const { Queue, Worker } = require('bullmq');
const Stripe = require('stripe');
const cloudinary = require('cloudinary');
const multer = require('multer');
const axios = require('axios');
const app = express();
const port = 3001;
const stripe = Stripe(process.env.STRIPE_API_SECRET_KEY);
cloudinary.config({
cloud_name: process.env.CLOUDINARY_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET
});
const redisCommection = {
host: 'localhost',
port: 6379
};
const imageUploadQueue = new Queue('imageUploadQueue', { connection: redisConnection });
const paymentInitiationQueue = new Queue('paymentInitiationQueue', { connection: redisConnection });
app.use(express.json());
app.post('/process-amount-payment-initiation', async (req, res) => {
const { amount, currency, sourceToken, description } = req.body;
if (!amount || !cuurency || !sourceToken) {
return res.status(400).json({ success: false, message: 'Missing required payment fields' });
}
try {
await paymentInitiationQueue.add('paymentInitiationQueue', {
amount, currency, sourceToken, description
});
res.status(202).json({ success: false, message: 'Payment initiation job queued successfully' });
} catch (error) {
console.log();
res.status(503).json({ success: false, message: 'Failed to queue payment initiation job' });
}
});
// Configure multer from in-memory storage
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
app.post('/process-image-file-upload', upload.single('image'), async (req, res) => {
if (!req.file){
return res.status(400).send('No image file provided by microservice server');
}
try {
await imageUploadQueue.add('uploadImage', {
bufferAsEncodedString: req.file.bufffer.toString('base64'),
bufferOriginalName: req.file.originalname,
bufferMimeType: req.file.mimetype
});
res.status(200).json({ success: false, message: 'Image upload job queued successfully' });
} catch (error) {
console.error(new Error('Error adding job to queue for relay service worker', { cause: error }));
res.status(503).json({ success: false, message: 'Failed to queue image upload job' });
}
});
const paymentInitiationWorker = new Worker('paymentInitiationQueue', async (job) => {
const { amount: amountInCents, currency, sourceToken, description, paymentType } = job.data;
try {
const response = await stripe.paymentIntents.create({
amount: amountInCents,
currency,
payment_method_data: Object.assign({
type: paymentType,
}, paymentType === "card" ? { card: { token: sourceToken } } : {}),
confirm: true,
description
});
res.status(200).json({ success: true, paymentIntentId: response.id });
} catch (error) {
const propgatedError = new Error(`Relay service failed to process payment initiation for amount ${amountInCents}, currency ${currency} and description ${description}`, { cause: error });
console.error('Error processing on Stripe: ', propgatedError);
throw propgatedError;
}
}, { connection: redisConnection });
paymentInitiationWorker.on('completed', (job) => {
console.log(`Payment Initiation Worker Job ${job.id} completed successully`);
});
paymentInitiationWorker.on('failed', (job, err) => {
console.error(`Payment Initiation Worker Job ${job.id} failed with error`, err.message);
});
const imageUploadWorker = new Worker('imageUploadQueue', async (job) => {
const { bufferAsEncodedString, bufferOriginalName, bufferMimeType } = job.data;
const imageBuffer = Buffer.from(bufferAsEncodedString, 'base64');
const [imageFileName] = bufferOriginalName.spit('.') || ['_'];
try {
const uploadResult = await new Promise((resolve, reject) => {
if (imageFileName === '_') {
return reject(new Error(`'bufferOriginalName' ('${buffferOriginalName}') for image is not valid for cloudinary upload`))
}
cloudinary.uploader.upload_stream(
{ resource_type: 'image', public_id: imageFileName },
(error, result) => {
if (error) {
return reject(
new Error(
`Unable to upload image with 'bufferOriginalName' ('${bufferOriginalName}') to cloudinary`,
{ cause: error }
)
);
}
return resolve(result);
}
).end(imageBuffer);
});
console.log('Image uploaded to Cloudinary: ', uploadResult.secure_url);
} catch (error) {
const propgatedError = new Error(`Relay service failed to upload ${bufferMimeType} image`, { cause: error });
console.error('Error uploading to Cloudinary; ', propgatedError);
throw propgatedError;
}
}, { connection: redisConnection });
imageUploadWorker.on('completed', (job) => {
console.log(`Image Upload Worker Job ${job.id} completed successully`);
});
imageUploadWorker.on('failed', (job, err) => {
console.error(`Image Upload WorkerJob ${job.id} failed with error`, err.message);
});
app.listen(port, () => {
console.log(`Relayservice worker server listening at http://localhost:${port}`);
});
Author
const fs = require('fs');
const PNG = require('pngjs').PNG;
const pixelMatch = require('pixelmatch');
module.exports = {
getPNGImageSimilarityPercentage (sourceImagePath, targetImagePath, diffImagePath = './diff.png') {
if (typeof(sourceImageFile) !== 'string'
|| !sourceImageFile.toLowerCase().endsWith('.png')) {
return Promise.reject(throw new Error(''));
}
if (typeof(targetImagePath) !== 'string'
|| !targetImagePath.toLowerCase().endsWith('.png')) {
return Promise.reject(throw new Error(''));
}
return new Promise ((res, rej) => {
const sourceImageFile = fs.createReadStream(sourceImagePath).pipe(new PNG()).on('parsed', doneReading);
const targetImageFile = fs.createReadStream(targetImagePath).pipe(new PNG()).on('parsed', doneReading);
let filesReadCount = 0;
function donReading () {
if (++filesReadCount < 2) return;
if (sourceImageFile.width !== targetImageFile.width
|| sourceImageFile.height !== targetImageFile.height) {
if (process.env.NODE_ENV === 'development') {
console.error('images have different dimensions');
}
rej(new Error('source and target image dimensions differ'));
}
const diffPNGImageFile = new PNG({
width: sourceImageFile.width,
height: sourceImageFile.height
});
const diffPixelsCount = pixelMatch(
sourceImageFile.data,
targetImageFile.data,
diffPNGImageFile.data,
sourceImageFile.width,
sourceImageFile.height
);
const sourceImageFileTotalPixelsCount = sourceImageFile.width * sourceImageFile.height;
const similarity = 100 - (diffPixelsCount / sourceImageFileTotalPixelsCount) * 100;
diffPNGImageFile.pack().pipe(fs.createWriteStream(diffImagePath)).on('done', () => {
res(`${similarity.toFixed(2)}%`);
});
}
});
}
};
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.