繁体   English   中英

IO用node-js编写

[英]IO writing in node-js

我有一个node.js(语法实际上是Typescript)应用程序:

  • 在某些HTTP请求处理程序中,异步将文件每日写入文件,
  • 在午夜重置该文件的cron作业(在使用node-cron模块完成的节点应用程序内部)

非阻塞事件循环循环对我来说不是很清楚(如果我弄错的话, 它不是幕后的单线程 ),而且我担心cron模块在写入文件时会重置文件的情况。

我需要担心吗? 就像在我承诺的fs.writeFile正在写入时设置的全局标志一样? 有没有更优雅的处理方式?

感谢和抱歉,如果这是一个愚蠢的问题。

这是我的代码的骨架:

import * as fs from 'fs';
import * as path from 'path';
import { CronJob } from 'cron';
import { pfs } from './promisifiedFs';

const daily_file = '/path_to_my_file'


new CronJob('0 0 * * * *', function() {
  fs.writeFileSync(daily_file, 0, {'flag': 'w'});
}, null, true);


// somewhere called inside an HTTP GET handler
async function doBill(data) {

  const something = //....

  const currentCountRaw = await pfs.readfilePromisified(daily_file, 'utf-8');
  const currentCount = parseFloat(currentCountRaw) || 0;
  await pfs.writeFilePromisified(daily_file, currentCount + something, {'flag': 'w'});

}

在Node.js中, 您的代码在单个线程中运行。 它是单线程的,除非您正在使用执行异步I / O的本机模块,而这些模块恰好将工作负载卸载到线程池中(并非总是如此), 或者如果您使用集群模块。

当您在脚本中使用writeFileSync时,主线程将一直阻塞,直到您完成该操作为止,并且不会并行执行其他任何操作。

编辑:如注释中所述,有可能发生以下情况:cron作业在读取和写入之间运行。 还有另一种情况不太可能发生,但有可能发生:异步写入已在运行,并且cronjob运行。 因此,我恢复了我的说法,因为它是错误的,建议您创建一个互斥体,如变量或锁定文件。

我建议使用异步队列 (如果您仅运行节点应用程序的一个实例)或锁文件 (如果您打算集群或使用多个进程)之类的东西。

下面是一些代码(我相信)将复制我所上述,这个问题通过写这应该增加多写碰撞的机会更大价值。

我的计算机似乎要执行的操作是fs.writeFileSync然后…什么都不做? 我可能会误会,但这是我正在使用的代码。 我选择使用co而不是async/await来避免进行转换。

const fs = require('fs');
const co = require('co');
const crypto = require('crypto');

function wait(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

function now() {
  return new Date().toISOString();
}

function log(...args) {
  return console.log(now(), ...args);
}

const file = './output.txt';

log('generating bytes...');
const bytes = crypto.randomBytes(100000000);
log('done generating bytes');

function writeAsync() {
  return new Promise((resolve, reject) => {
    return fs.writeFile(file, bytes.toString('base64'), { 'flag': 'w' }, err => {
      if (err) {
        return reject(err);
      }
      return resolve();
    });
  });
}

function writeSync() {
  fs.writeFileSync(file, 'FINDMEFINDMEFINDME', { 'flag': 'w' });
}

function run() {
  return co(function*() {
    log('before write async');
    const promise = writeAsync().then(() => log('after write async'));
    const ms = 1;
    log(`waiting for ${ms} ms`);
    yield wait(ms);
    log('done waiting');
    log('before write sync');
    writeSync();
    log('after write sync');
    yield promise;
  });
}

run().catch(err => console.error(err));

输出示例:

2016-10-03T22:52:05.032Z generating bytes...
2016-10-03T22:52:06.846Z done generating bytes
2016-10-03T22:52:06.848Z before write async
2016-10-03T22:52:06.999Z waiting for 1 ms
2016-10-03T22:52:07.001Z done waiting
2016-10-03T22:52:07.001Z before write sync
2016-10-03T22:52:07.012Z after write sync
2016-10-03T22:52:08.623Z after write async

行为:

似乎文件输出包含writeAsync()的结果,而writeSync()对输出没有影响。 老实说,我有点希望抛出一个错误。 甚至writeSync()'FINDMEFINDMEFINDME'放置在其他代码的中间,但是我无法在输出文件中找到该字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM