serveless aws gcp speed
This problem, let me think my stupid manager and Smart
Information Security Consultant before company.
Information Security Consultant Say GCP is very safe... Ya safe so customer lose.
GCP logging winston LoggingWinston severity
If you want to control severity at LoggingWinston.
https://stackoverflow.com/questions/58055551/structured-logs-in-google-cloud-run-not-being-parsed-using-winston-for-logging
const winston = require('winston');
const useFormat = winston.format.combine(
winston.format((info, opts) => {
let level = info.level.toUpperCase();
if(level === 'VERBOSE') {
level = 'DEBUG';
}
info['severity'] = level;
delete info.level;
return info;
})(),
winston.format.json());
const { LoggingWinston } = require('@google-cloud/logging-winston');
const loggingWinston = new LoggingWinston();
const logger = winston.createLogger({
level: 'debug',
format: useFormat,
transports: [
new winston.transports.Console(),
loggingWinston
]
});
Firebase deploy default vpcConnector vpc-Connector gcloud vpc
oooxxxoooxxx: vpc Connector name
aaabbbaaabbb: your firebase project
Firebase deploy default vpcConnector vpc-Connector
node_modules\firebase-tools\lib\gcp\cloudfunctions.js
_createFunction
const data ADD
vpcConnector: 'oooxxxoooxxx',
Failed
gcloud VPC
VPC_CONNECTOR=dosportsapi-redis01
projects/aaabbbaaabbb/locations/us-central1/connectors/oooxxxoooxxx
gcloud beta functions deploy api \
--runtime nodejs10 \
--trigger-http \
--region us-central1 \
--vpc-connector $VPC_CONNECTOR \
--egress-settings private-ranges-only \
--memory 2048MB
node.js express.js sequelize redis cache
http://liu-xin.me/2017/03/24/%E8%AE%A9%E5%86%99%E5%85%A5%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E6%95%B0%E6%8D%AE%E8%87%AA%E5%8A%A8%E5%86%99%E5%85%A5%E7%BC%93%E5%AD%98/
const to = require('await-to-js').default;
const Redis = require('ioredis');
const redis = new Redis(ooxxooxx);
function Cache() {}
Cache.get = async function(key) {
const [err, res] = await to(redis.get(key));
if (err) {console.error('REDIS::Cache::get]', err); return null;}
return JSON.parse(res);
};
Cache.set = async function(key, value) {
value = JSON.stringify(value);
const [err] = await to(redis.set(key, value));
if (err) {console.error('REDIS::Cache::set]', err); }
};
//
// sequelize.query
//
async function CacheSequelizeQuery(sequelize, sql, params, redisKey) {
const cacheData = await Cache.get(redisKey);
if (cacheData) return cacheData; // not empty return cache data
const [err, lists] = await to(sequelize.query(sql, params));
if (err) throw err;
if (lists) await Cache.set(redisKey, lists); // not empty set cache data
return lists;
}
//
// findOneCache
//
Sequelize.Model.findOneCache = async function() {
let redisKey;
for (const parms of Object.values(arguments)) {
if (parms.where) redisKey = [this.name, JSON.stringify(parms.where)].join(':');
}
const cacheValue = await Cache.get(redisKey);
if (cacheValue) return JSON.parse(cacheValue);
const result = await Sequelize.Model.findOne.apply(this, arguments);
Cache.set(redisKey, JSON.stringify(result));
return result;
};
node.js redis special delete del
https://github.com/luin/ioredis
const Redis = require('ioredis');
const redis = new Redis();
const delScript = `
local all_keys = {};
local keys = {};
local done = false;
local cursor = "0"
repeat
local result = redis.call("SCAN", cursor, "match", KEYS[1], "count", KEYS[2])
cursor = result[1];
keys = result[2];
for i, key in ipairs(keys) do
all_keys[#all_keys+1] = key;
end
if cursor == "0" then
done = true;
end
until done
for i, key in ipairs(all_keys) do
redis.call("DEL", key);
end
return true;
`;
redis.defineCommand('del', {
numberOfKeys: 2,
lua: delScript
});
redis.del('login:202007*', 10000, function(error, result) {
console.log('error: ', error);
console.log('result: ', result);
});
javascript functions parm default value
https://stackoverflow.com/questions/6600868/set-default-value-of-javascript-object-attributes
// default num: 0, unit: 'pics'
function items(op) {
const { num, unit } = Object.assign({}, { num: 0, unit: 'pics'}, op);
}
firebase functions cold start use Express.js node.js get problem
System on firebase functions always have problems that code start.
https://medium.com/@siriwatknp/cold-start-workaround-in-firebase-cloud-functions-8e9db1426bd3
So
google office
https://firebase.google.com/docs/functions/networking
const http = require('http');
const functions = require('firebase-functions');
// Setting the `keepAlive` option to `true` keeps
// connections open between function invocations
const agent = new http.Agent({keepAlive: true});
exports.function = functions.https.onRequest((request, response) => {
req = http.request({
host: '',
port: 80,
path: '',
method: 'GET',
agent: agent, // Holds the connection open after the first invocation
}, res => {
let rawData = '';
res.setEncoding('utf8');
res.on('data', chunk => { rawData += chunk; });
...
Two line let me confused. Not only me.
const agent = new http.Agent({keepAlive: true});
agent: agent, // Holds the connection open after the first invocation
Some guy same me.
Get same problem.
https://stackoverflow.com/questions/56912118/how-can-i-maintain-persist-a-cloud-functions-connection-using-expressjs
Success??
https://stackoverflow.com/questions/55425015/how-to-keep-alive-dialogflow-firebase-function-to-avoid-new-connection-time-wastThanks Max. However I found the answer to this problem from the same link I posted above (i.e. firebase.google.com/docs/functions/networking). Just adding two lines of code solved the problem. Now response is quite prompt. I added following lines: 1. const agent = new http.Agent({keepAlive: true}); 2. agent: agent, – Vipul Sisodia Apr 2 '19 at 19:04
See Express.js
https://nodejs.org/dist/latest-v10.x/docs/api/http.html#http_new_agent_options
Not thing can Try.
Other way
https://medium.com/@onufrienkos/keep-alive-connection-on-inter-service-http-requests-3f2de73ffa1https://stackoverflow.com/questions/60667847/unable-to-verify-leaf-signature-from-request-with-firebase-functions-node-js-wit index.js
require('https').globalAgent.keepAlive = true;
const functions = require('firebase-functions');
const express = require('express');
const app = express();
...
exports.api = functions.runWith(runtimeOpts).https.onRequest(app);
require('https').globalAgent.keepAlive = true;
Try by yourself.
nodejs node.js console.log util.format ...args for logging log
For logging mulit args with "%O"
const util = require('util');
function d(...args) {
if (typeof (console) !== 'undefined') {
console.log('[Logging]', util.format(...args));
}
}
nodejs express cache redis
https://sematext.com/blog/expressjs-best-practices/
const express = require('express')
const app = express()
const redis = require('redis')
const redisClient = redis.createClient(6379)
async function getSomethingFromDatabase (req, res, next) {
try {
const { id } = req.params;
const data = await database.query()
// Set data to Redis
redisClient.setex(id, 3600, JSON.stringify(data))
res.status(200).send(data)
} catch (err) {
console.error(err)
res.status(500)
}
}
function cache (req, res, next) {
const { id } = req.params
redisClient.get(id, (err, data) => {
if (err) {
return res.status(500).send(err)
}
// If data exists return the cached value
if (data != null) {
return res.status(200).send(data)
}
// If data does not exist, proceed to the getSomethingFromDatabase function
next()
})
}
app.get('/data/:id', cache, getSomethingFromDatabase)
app.listen(3000, () => console.log(`Server running on Port ${port}`))
vs code 無法使用eslint
In personal setting.json for vs code
"eslint.workingDirectories": [
{ "mode": "auto" }
],
Promise.all map
const arr = {};
await Promise.all(
UsersQuery.map(async function (data) {
const city = await db.sequelize.query(`
select * from city
`,
type: db.sequelize.QueryTypes.SELECT
});
arr[data.user_id] = city[0].name;
})
}
UsersQuery.forEach(async function (data, index) {
this[index].name = arr[data.user_id];
}, UsersQuery);
nodejs moment moment-timezone
Use express, moment, moment-timezone
Server timezone 0
Client time zone +8
Server run result:
Client run result:
const moment = require('moment-timezone');
app.get('/moment', (req, res) => {
const datestr = '2020-07-01';
res.status(200).json({
local_offset: moment(datestr).utc(),
local_unix: moment(datestr).unix(),
zone0_unix: moment(datestr).zone(0).unix(),
zone8_unix: moment(datestr).zone(8).unix(),
timezone0_unix: moment.tz(datestr, 'GMT').unix(),
timezone8_unix: moment.tz(datestr, 'Asia/Taipei').unix(),
});
});
// No use, just for keep
function dateForTimezone(offset, d) {
// Copy date if supplied or use current
d = d? new Date(+d) : new Date();
// Use supplied offset or system
offset = offset || -d.getTimezoneOffset();
// Prepare offset values
var offSign = offset < 0? '-' : '+';
offset = Math.abs(offset);
var offHours = ('0' + (offset/60 | 0)).slice(-2);
var offMins = ('0' + (offset % 60)).slice(-2);
// Apply offset to d
d.setUTCMinutes(d.getUTCMinutes() - offset);
return offSign + offHours + ':' + offMins;
// Return formatted string
return d.getUTCFullYear() +
'-' + ('0' + (d.getUTCMonth()+1)).slice(-2) +
'-' + ('0' + d.getUTCDate()).slice(-2) +
'T' + ('0' + d.getUTCHours()).slice(-2) +
':' + ('0' + d.getUTCMinutes()).slice(-2) +
':' + ('0' + d.getUTCSeconds()).slice(-2) +
'.' + ('000' + d.getUTCMilliseconds()).slice(-3) +
offSign + offHours + ':' + offMins;
}
IMPORT
Server timezone 0
Client time zone +8
Server run result:
{
"local_offset": "2020-06-30T16:00:00.000Z",
"local_unix": 1593532800,
"zone0_unix": 1593532800,
"zone8_unix": 1593532800,
"timezone0_unix": 1593561600,
"timezone8_unix": 1593532800
}
Client run result:
{
"local_offset": "2020-07-01T00:00:00.000Z",
"local_unix": 1593561600,
"zone0_unix": 1593561600,
"zone8_unix": 1593561600,
"timezone0_unix": 1593561600,
"timezone8_unix": 1593532800
}
Conclusion
moment().zone().unix() Auto fix zone / utc
moment("").tz("GMT").unix() Auto fix zone / utc
moment().tz("", "GMT").unix() No auto fix zone / utc
typeorm connection
const typeorm = require("typeorm");
const connectionManager = require("typeorm").getConnectionManager();
//const connectionManager = typeorm.getConnectionManager();
const connected = connectionManager.has("default");
if(!connected){
// ? load connection options from ormconfig or environment
//const connectionOptions = await getConnectionOptions();
connectionManager.create({
//name: "default",
type: "mysql",
// "extra": {
// "socketPath": "/cloudsql/ooxxooxx"
// },
host: "oo.xx.oo.xx",
port: 3306,
username: "root",
password: "ooxxooxx",
database: "ooxxdb",
synchronize: false,
logging: true, // this.env === 'dev' ? true : false
ssl: SSL,
keepConnectionAlive: false,
});
}
try {
db = connectionManager.get();
if(!connected){
await db.connect();
console.log('connect .... OK!');
}
}catch(error) {
console.log("TypeORM Error: ", error);
};
var ranks = await db.query("select * from users");
nodexjs expressjs ajv apidoc converter generator restclient curl postman
ajv schema to apidoc schema
https://github.com/willfarrell/apidoc-plugin-schema
required can't product doc.
converter
https://github.com/apidoc/apidoc#converter
to swagger
https://github.com/fsbahman/apidoc-swagger
postman collection to apidoc
https://github.com/bonzzy/docmaster
RestClient -> curl -> postman
https://github.com/willfarrell/apidoc-plugin-schema
required can't product doc.
converter
https://github.com/apidoc/apidoc#converter
to swagger
https://github.com/fsbahman/apidoc-swagger
postman collection to apidoc
https://github.com/bonzzy/docmaster
RestClient -> curl -> postman
promise.all error catch
https://stackoverflow.com/questions/30362733/handling-errors-in-promise-all
Alternately, if you have a case where you don't particularly care about the values of the resolved promises when there is one failure but you still want them to have run, you could do something like this which will resolve with the promises as normal when they all succeed and reject with the failed promises when any of them fail:
Promise.all(state.routes.map(function(route) {
return route.handler.promiseHandler().catch(function(err) {
return err;
});
}))
.then(function(arrayOfValuesOrErrors) {
// handling of my array containing values and/or errors.
})
.catch(function(err) {
console.log(err.message); // some coding error in handling happened
});
Alternately, if you have a case where you don't particularly care about the values of the resolved promises when there is one failure but you still want them to have run, you could do something like this which will resolve with the promises as normal when they all succeed and reject with the failed promises when any of them fail:
function promiseNoReallyAll (promises) {
return new Promise(
async (resolve, reject) => {
const failedPromises = []
const successfulPromises = await Promise.all(
promises.map(
promise => promise.catch(error => {
failedPromises.push(error)
})
)
)
if (failedPromises.length) {
reject(failedPromises)
} else {
resolve(successfulPromises)
}
}
)
}
訂閱:
文章 (Atom)