惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
博客园 - 【当耐特】
Jina AI
Jina AI
雷峰网
雷峰网
J
Java Code Geeks
腾讯CDC
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 叶小钗
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
The Register - Security
The Register - Security
罗磊的独立博客
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
有赞技术团队
有赞技术团队
The Hacker News
The Hacker News
Scott Helme
Scott Helme
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
The Exploit Database - CXSecurity.com
Vercel News
Vercel News
Cisco Talos Blog
Cisco Talos Blog
美团技术团队
B
Blog RSS Feed
L
LangChain Blog
大猫的无限游戏
大猫的无限游戏
SecWiki News
SecWiki News
Webroot Blog
Webroot Blog
N
News | PayPal Newsroom
D
Docker
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
W
WeLiveSecurity
C
CERT Recently Published Vulnerability Notes
L
Lohrmann on Cybersecurity
T
Tenable Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
阮一峰的网络日志
阮一峰的网络日志
I
Intezer
Hugging Face - Blog
Hugging Face - Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org

JieJiSS' Blog

为 SQLAlchemy Model 添加 type hint 和 type check Boot an Arch Linux RISC-V using qemu-system 关于基于机器学习的多目标对象追踪算法的文献综述 - JieJiSS' Blog RV64 板子更换 rootfs 指南 - JieJiSS' Blog ACTF2022 safer-tg-bot-{1,2} WP - JieJiSS' Blog A RISC-V gcc pitfall revealed by a glibc update Setup an Arch Linux RISC-V Development Environment How's the GDPR (used to) related to my blog Rust is incompatible with LLVM, at least partially python-mtrpacket 在 riscv64 上编译测试不通过 - JieJiSS' Blog 快速获得 RISC-V 开发环境 - JieJiSS' Blog 在 RISC-V 上编译 Node.js 16 Redmi AirDots 3 Pro 连接电脑后蓝牙类别不正确的解决方案 为什么 ArrowFunction 不能 new - JieJiSS' Blog Bilibili 2020-10-24 CTF WriteUp - JieJiSS' Blog 对于又一种对SS流式加密的攻击(奇虎团队)的详细分析 - JieJiSS' Blog 在MacOS上配置dnscrypt-proxy(免分流) - JieJiSS' Blog 市县中心点坐标(经纬度) - JieJiSS' Blog 二项式定理及其推广公式的一种简单理解办法 - JieJiSS' Blog
解构赋值踩坑:神秘失踪的数据 - JieJiSS' Blog
2022-03-15 · via JieJiSS' Blog

话说在我们 PLCT ArchRV 组,基础设施都是我们自己搭出来的,分工、打标记、追踪状态全部靠 gh: XieJiSS/plct-archrv-pkg-botgh: cubercsl/archrv-pkg-notification-botgh: Ast-x64/plct-archrv-status-worker 实现。近日我们在维护标记和追踪状态时,发现 plct-archrv-pkg-bot (以下简称 bot)在重启时会丢失几条记录。

最开始,怀疑是重启的时候还有数据没写入到磁盘,导致数据丢失。但是经过排查,发现并不太可能,理论上所有的数据都是在修改时当场写入磁盘的。保险起见,增加了使用同步 IO 的 storePackageMarksSync,通过 npm: async-exit-hook 在进程退出时强制保存。然而还是丢数据。

看 log 可以确认,在退出时把内存里的数据全部写入到磁盘了,那丢数据是怎么回事呢?

又开始考虑是不是 race condition,于是通过 npm: lockfile 实现了进程的保护锁,确保同时只有一个 bot 进程在运行。除了没效果以外,效果非常好。看来也不是多进程并行写入的问题。

最后经过排查,发现问题的根源在 exportimport 上。

最小可复现样例如下:

1
2
3
4
5
6
7
8
9
10
11
12

let A = [1, 2, 3, null];

function cleanUp() {
A = A.filter(num => typeof num === "number");
}

function showData() {
console.log(A);
}

module.exports = { A, cleanUp, showData };
1
2
3
4
5
6
7
8

const { A, cleanup, showData } = require("./a");

A.push(4);
cleanUp();
A.push(5);
A.push(6);
showData();

可以看到,在执行 cleanUp 之后的数据全部丢失了。这是因为在 a.js 里对 A 重新赋值过后,b.js 解构赋值得到的 Aa.js 里的 A 不再指向同一个对象。解构赋值出来的 identifier A 指向的是 module.exportsA 属性在解构赋值那一时刻所指向的内存,随后执行的 A = A.filter 只是在 a.js 内部修改了 A 的指向,外部解构赋值出的 A 并不会随之更新。我们可以用 cpp 来翻译一下第一种写法:

1
2
3
const auto *A = a.A;
a.A = new vector<int>();

概括一下:如果把 JS 里面解构赋值拿到的东西当做 &ref 来理解(这是常有的事)就会导致这种 inconsistency 的出现。

如果想修复这个问题,需要在 a.js 里面把 A 声明为 const,随后将 Array#filter 替换为自己实现的 in-place filter,详见这个 commit。当然你也可以在 b.js 里始终使用 a.A 的方式来访问 A

来源:https://blog.jiejiss.com/