middleware/controllers/transactions.js (103 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ const axios = require('axios'); const { getEnv } = require('../utils/envParser'); const logger = require('../utils/logger'); /** * Retrieves profiling data and sends it as a response. * * @param {import('express').Request} req - The Express request object. * @param {import('express').Response} res - The Express response object. * @param {Object} req.body - The body of the request. * @param {string} req.body.query - The query parameter to filter the profiling data. Send it without .cpu prefix * @returns {void} - Sends the profiling data as a response. */ async function setValue(req,res){ const baseUrl = `${getEnv("CPP_TRANSACTIONS_API_BASE_URL")}/commit` const data = req.body let config = { method: 'post', maxBodyLength: Infinity, url: baseUrl, data : data }; try { let response = await axios.request(config) const responseData = response?.data.split(": ") return res.send({ id: responseData[1] }) } catch (error) { logger.error(error) return res.status(500).send({ error: error }) } } /** * Retrieves profiling data and sends it as a response. * * @param {import('express').Request} req - The Express request object. * @param {import('express').Response} res - The Express response object. * @param {Object} req.body - The body of the request. * @param {string} req.body.query - The query parameter to filter the profiling data. Send it without .cpu prefix * @returns {void} - Sends the profiling data as a response. */ async function getValue(req,res){ const { key } = req.params const baseUrl = `${getEnv("CPP_TRANSACTIONS_API_BASE_URL")}/${key}` const data = req.body let config = { method: 'get', maxBodyLength: Infinity, url: baseUrl, }; try { let response = await axios.request(config) return res.send(response?.data) } catch (error) { logger.error(error) return res.status(500).send({ error: error }) } } /** * Warms the cache by inserting 50 random key-value pairs. * * @param {import('express').Request} req - The Express request object. * @param {import('express').Response} res - The Express response object. * @returns {void} - Sends a success message or an error as a response. */ async function calculateP99(req, res) { const { samples = 50 } = req.body const baseUrl = `${getEnv("CPP_TRANSACTIONS_API_BASE_URL")}/commit`; let promises = []; let responseTimes = []; for (let i = 0; i < Math.min(50,samples); i++) { const randomValue = getRandomInt(samples) const key = `key_${randomValue}`; const value = `value_${randomValue}`; const data = { id: key, value: value, }; const config = { method: "post", maxBodyLength: Infinity, url: baseUrl, data: data, }; promises.push( new Promise(async (resolve, reject) => { const startTime = Date.now(); try { const response = await axios.request(config); const responseTime = Date.now() - startTime; responseTimes.push(responseTime); logger.info(`Key: ${key} set successfully. Response time: ${responseTime}ms`); resolve(response.data); } catch (error) { logger.error(`Failed to set key: ${key}. Error: ${error.message}`); reject(error); } }) ); } try { await Promise.all(promises); responseTimes.sort((a, b) => a - b); const p99Index = Math.ceil(0.99 * responseTimes.length) - 1; const p99 = responseTimes[p99Index]; return res.send({ message: `Cache warmed with ${samples} random values successfully.`, p99, }); } catch (error) { logger.error("Error warming the cache:", error.message); return res.status(500).send({ error: "Failed to warm cache.", }); } } function getRandomInt(max) { return Math.floor(Math.random() * max); } module.exports = { setValue, getValue, calculateP99 }