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 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/
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);
}
mysql virtual colume alert
ALTER TABLE `user`
ADD `last name` VARCHAR(50)
AS (
case `name`
when admin then 0
else CONCAT(`name`, 'user')
end
)
;
vs code vscode remote ssh Error: EACCES: permission denied
vscode remote ssh Error: EACCES: permission denied
1. make sure that sudo -u newuser -i works in a regular ssh session without requesting a password
1. make sure that sudo -u newuser -i works in a regular ssh session without requesting a password
2. remove "-o RemoteCommand=none" and "bash" from extension.js like so
Get Problem:
sed -i s/"-o RemoteCommand=none"/""/ ~/.vscode/extensions/ms-vscode-remote.remote-ssh-*/out/extension.js
sed -i s/"bash"/""/ ~/.vscode/extensions/ms-vscode-remote.remote-ssh-*/out/extension.js
3. create an ssh config entry with a RemoteCommand like this one:
Host pi-for-newuser
Hostname pi
User pi
RemoteCommand sudo -u newuser -i
mesg: ttyname failed: Inappropriate ioctl for device
RequestTTY Yes
RemoteCommand sudo -i
firebase functinos cookie only __session
https://firebase.google.com/docs/hosting/manage-cache?hl=zh-cn#using_cookies
将 Firebase 托管与 Cloud Functions 或 Cloud Run 搭配使用时,Cookie 通常会从传入的请求中剥离出来。这是实现高效的 CDN 缓存行为所必需的。只有特别指定的 __session Cookie 可以传入应用执行过程中。
__session Cookie(如果存在)会自动成为缓存键的一部分,也就是说,使用不同 Cookie 的两个用户绝不会收到彼此的已缓存响应。只有在您的应用根据用户授权提供不同的内容时,您才能使用 __session Cookie。
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.
mysql json mariadb
最近寫mysql 發現 原來 mysql 在json內容時,也有支援一些操作
https://www.cnblogs.com/chuanzhang053/p/9139624.html
https://medium.com/micheh/%E5%9C%A8-mysql-%E4%BD%BF%E7%94%A8-json-5796a65701ad
再加上 mysql 還有另一個譆能 虛疑欄位 GENERATED ALWAYS AS
http://blog.changyy.org/2017/09/mysql-json-mysql-57.html
基本上可以把json內的某欄位值當成 virutal colume, 直接輸出
覺得這樣可以玩出很多變化
https://www.cnblogs.com/waterystone/p/5626098.html
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));
}
}
[轉]網站使用體驗三大核心指標 – LCP, FID, CLS
https://www.darrenhuang.com/core-web-vitals-lcp-fid-cls.html?fbclid=IwAR2-n-h0j-BR73sD4Vsino1ObtjDyVe3xkhNcs7xmtcn14Kk84rWO-06lPs
瀏覽器插件
這是官方出的Chrome挿件,能夠在瀏覽時即時回報該網頁的LCP, FID, CLS。
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);
sqlmap
docker https://hub.docker.com/r/googlesky/sqlmap
執行指令:
docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap -h
GET
docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap --url='https://test.com/date=2020-04-01' --level=5 --risk=3
POST & header token
docker run --rm -it -v /tmp/sqlmap:/root/.sqlmap/ googlesky/sqlmap --url='http://oo.xx.oo.xx:5000/user/info' --headers='Authorization: bearer eyJhbGcoooooxxxxxoooooxx......' --data='{id: "u123"}' --level=5 --risk=3
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");
訂閱:
文章 (Atom)

