Node.js集群;仅在使用颜色

时间:2018-10-03 19:06:22

标签: node.js terminal ansi-escape conemu terminal-color

Нello!我正在运行具有多个节点的集群节点项目。他们做了相当多的控制台输出。我还希望能够进行漂亮的彩色输出。

我的问题:仅当使用颜色时,我才开始出现混乱的,具有比赛条件的控制台输出。

我一直在努力以解决问题,而我当前的设置是使群集中的每个节点都有自己的唯一字符串。这是节点将输出到控制台的唯一字符串。

let chars = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let getMyUniqueString = () => {
  return chars[Math.floor(Math.random() * chars.length)].repeat(100);
};

我运行了许多节点,这些节点正在使用此函数来确定其唯一的字符串,并且看到类似以下的内容:

Console output without any jumbling

那不是很漂亮!无论所有这些节点输出了多长时间和多么疯狂,该控制台输出都不会混乱。

现在,我尝试使用只包含一点点颜色的独特字符串:

let chars = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let getMyUniqueString = () => {
  let redEscSeq = '\x1b[41m';
  let clearEscSeq = '\x1b[0m';
  let aRedBoxOfText = redEscSeq + '  ' + clearEscSeq;
  let repeatedChars = chars[Math.floor(Math.random() * chars.length)].repeat(100);
  return aRedBoxOfText + repeatedChars;
};

看看我的一些结果看起来多么可悲!

enter image description here

通过console.log函数,将数据跨所有节点发送到终端的唯一方法。

为什么console.log足够聪明,可以在没有颜色的情况下保持许多节点的输出不混乱,而在甚至包括一点点颜色的情况下,也不够聪明呢?

感谢您的帮助!

(仅供参考,下面的图像是我希望在彩色情况下能够始终看到的整齐的输出;它只是在每行前面加上一个红色框(两个带有红色背景色的空格):)

enter image description here

编辑:虽然此问题存在于本机Windows“ cmd.exe”控制台,PowerShell控制台和ConEmu(如屏幕截图所示的漂亮的第三方窗口终端)中,但在Cygwin终端中不存在!在Cygwin中,即使有成千上万的颜色和异步输出,也不会出现任何混乱。我有什么办法可以鼓励这种在其他控制台上的Cygwin行为?

1 个答案:

答案 0 :(得分:1)

这是一个竞争条件,您几乎不可能对此做任何事情,也许只是向nodejs使用的库报告错误。

尽管Windows API本身实际上支持在单个API调用中打印多色字符串,如下所示:https://docs.microsoft.com/en-us/windows/console/writeconsoleoutput,其中每个字符都包含其颜色信息。但是它也不支持ANSI转义码。这不是javascript实际使用的。

Nodejs引擎使用名为libuv的库将字符串写入终端,该终端是跨平台的,并在内部转换ANSI转义码以完成正确的操作。但是,如果仔细查看source of libuv来处理ANSI转义代码,您会发现它在每个转义代码之后都会进行完整的缓冲区刷新,这意味着在一定程度上它必须成为多个Windows API调用才能打印一行文字。

在正常情况下,这显然不是问题,但是,如果您有多个线程进行编写,则意味着这些行的某些部分可能会变得混乱……就像您在此处看到的一样。

因此,这里的答案是没有解决方案。或者您也接受使用cygwin作为解决方案。