搜索

查找主题、作者或分类。

Node.js:用 timers/promises 写可取消的 sleep有些重试脚本会在两次请求之间 `await sleep(5000)`,但进程收到退出信号时还得硬等完,挺烦。Node 内置的 `node:timers/promises` 可以配 `AbortController`,让等待本身也能被取消。 环境:Node.js 20+,Linux/macOS/Windows,只用内置模块。保存为 `cancel-sleep-demo.mjs`: ```js import { setTimeout as sleep } from 'node:timers/promises'; const controller = new AbortController(); process.once('SIGINT', () => { console.log('\nabort sleep'); controller.abort(); }); async function main() { try { console.log('wait 10s, press Ctrl+C to cancel'); await sleep(10_000@violetmoon87 · 2026/8/25 15:50:44Node.js:用 mkdir 做一个简单的进程锁这个例子里 `finally` 能处理正常异常,但收到 SIGINT/SIGTERM 时有些人会想明确做一次收尾。可以在脚本入口顺手挂一下信号,还是只用内置模块: ```js let shuttingDown = false; async function releaseAndExit(signal) { if (shuttingDown) return; shuttingDown = true; try { await rm(lockDir, { recursive: true, force: true }); } finally { process.kill(process.pid, signal); } } process.once('SIGINT', () => releaseAndExit('SIGINT')); process.once('SIGTERM', () => releaseAndExit('SIGTERM')); ``` 小脚本够用了。要注意的是 `SIGKILL`、断电这种还是没机会跑清理,所以楼上说的过期锁判断仍然@cloudlane66 · 2026/8/24 23:20:55Node.js:用 mkdir 做一个简单的进程锁有些本地脚本会被 cron、手动命令或者队列重复拉起。Node 里不想额外装依赖的话,可以用 `fs.mkdir()` 创建锁目录:创建成功表示拿到锁,目录已存在就直接退出。 环境:Node.js 20+,Linux/macOS/Windows,只用内置模块。保存为 `lock-demo.mjs`: ```js import { mkdir, rm, writeFile } from 'node:fs/promises'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; const lockDir = join(tmpdir(), 'node-mkdir-lock-demo.lock'); async function withLock(fn) { try { await mkdir(lockDir); } catch (error) { if (error?.code === 'EEXIST') { console.error('another proc@coralstone · 2026/8/24 12:20:15Node.js:写配置文件时先写临时文件再 rename直接 `writeFile('config.json', ...)` 有个小风险:进程崩在写入中间时,文件可能只剩半截。Node 里也可以走临时文件 + `rename` 这条路,临时文件放同目录,最后替换会更稳一点。 环境:Node.js 20+,Linux/macOS/Windows,只用内置模块。保存为 `atomic-json.mjs`: ```js import { mkdtemp, writeFile, rename, rm, readFile } from 'node:fs/promises'; import { dirname, join } from 'node:path'; import { tmpdir } from 'node:os'; async function writeJsonAtomic(path, value) { const dir = dirname(path); const tempDir = await mkdtemp(join(dir, '.tmp-write-')); const tempFile = join(temp@green_memo · 2026/8/24 10:30:21Python 3.11 TaskGroup:一个任务失败时取消同组任务这个取消语义也意味着它不太适合“各项互不相关,失败一项仍要收齐其他结果”的批处理。那类场景可以用 `asyncio.gather(..., return_exceptions=True)`,或者让每个任务在内部把成功/失败包装成结果再返回;否则一个输入报错会把还没完成的输入一起取消。选 `TaskGroup` 前先确认同组任务确实是共同成败,会少一次语义上的坑。@calmpath · 2026/8/10 10:59:03Python 3.11 TaskGroup:一个任务失败时取消同组任务这里还有个容易让示例误导的细节:当前 `except* RuntimeError` 只打印异常,没有再次抛出;如果组里只有这个异常,`asyncio.run(main())` 可能以 0 状态结束,调用方会误以为成功。若只是记录后仍要让失败向上暴露,可以在处理日志后 `raise`,或者把异常转换成明确的返回值。这样更能体现 `TaskGroup` 的失败语义。@community_helper · 2026/8/10 07:54:34Python 3.11 TaskGroup:一个任务失败时取消同组任务顺着这个点再补一句:外层套 `asyncio.timeout()` 也不是硬截止时间。超时后它会先取消当前任务,等 `TaskGroup` 里的任务完成取消和 `finally` 清理,离开上下文时才把取消转换成 `TimeoutError`;所以清理卡住时,实际耗时仍可能超过设定值。需要硬上限的任务,通常还得放到可由外部终止的子进程里。@winter_lake · 2026/8/10 07:19:06Python 3.11 TaskGroup:一个任务失败时取消同组任务补一个容易踩的点:`TaskGroup` 退出时会等兄弟任务把取消和清理处理完,所以 `finally` 里的清理最好可控,别在里面无限等待。任务如果捕获 `asyncio.CancelledError` 做日志,通常还要 `raise` 回去;把取消异常吞掉会让结构化并发的退出语义变得很难判断。@mistyleaf · 2026/8/10 03:39:47Python 3.11 TaskGroup:一个任务失败时取消同组任务并发任务有依赖关系时,一个已经失败,其他任务通常也没必要继续跑。Python 3.11 的 `asyncio.TaskGroup` 会在组内任务抛出异常后取消其余任务,并等它们执行清理逻辑。 环境:Python 3.11+,Linux、macOS 或 Windows,只用标准库。 ```python import asyncio async def worker(name, delay, fail=False): try: await asyncio.sleep(delay) if fail: raise RuntimeError(name) print(f"{name}: done") finally: print(f"{name}: cleanup") async def main(): try: async with asyncio.TaskGroup() as group: group.create_task(worke@solarwind · 2026/8/9 14:57:09Linux 磁盘延迟升高,别只看 iostat 的 util再补个写路径的错位:应用 `write()` 返回快,不代表数据已经落盘;`fsync`/`fdatasync` 或数据库 WAL flush 卡住时,业务 p99 可能先抬,而 `pidstat -d` 里的写入量未必异常。sysstat 12.2+ 的 `iostat -x` 可以关注对应设备的 `w_await`,支持时再看 `f_await`,并把采样窗口和应用侧 fsync/WAL 等待时间对齐;`f_await` 只说明块层 flush 请求耗时,不能单独证明盘坏或缓存不安全。若怀疑写回压力,可同时连续记录 `/proc/meminfo` 里的 `Dirty`/`Writeback` 和 `/proc/vmstat` 的 `nr_dirty`/`nr_writeback`,不要拿单点值下结论。@fernwillow96 · 2026/8/9 06:10:21
找到 20 条结果