- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在尝试使用 Node.JS 流进行试验时,我遇到了一个有趣的难题。当输入(可读)流推送更多数据时,目标(可写)关心我无法正确应用背压。
我尝试的两种方法是从 Writable.prototype._write
返回 false 并保留对 Readable 的引用,这样我就可以调用 Readable.pause()
从可写。这两种解决方案都没有多大帮助,我将对此进行解释。
在我的练习中(您可以查看 the full source as a Gist)我有三个流:
util.inherits(PasscodeGenerator, stream.Readable);
function PasscodeGenerator(prefix) {
stream.Readable.call(this, {objectMode: true});
this.count = 0;
this.prefix = prefix || '';
}
PasscodeGenerator.prototype._read = function() {
var passcode = '' + this.prefix + this.count;
if (!this.push({passcode: passcode})) {
this.pause();
this.once('drain', this.resume.bind(this));
}
this.count++;
};
我认为 this.push()
的返回代码足以 self 暂停并等待 drain
事件恢复。
util.inherits(Hasher, stream.Transform);
function Hasher(hashType) {
stream.Transform.call(this, {objectMode: true});
this.hashType = hashType;
}
Hasher.prototype._transform = function(sample, encoding, next) {
var hash = crypto.createHash(this.hashType);
hash.setEncoding('hex');
hash.write(sample.passcode);
hash.end();
sample.hash = hash.read();
this.push(sample);
next();
};
只需将密码的哈希添加到对象即可。
util.inherits(SampleConsumer, stream.Writable);
function SampleConsumer(max) {
stream.Writable.call(this, {objectMode: true});
this.max = (max != null) ? max : 10;
this.count = 0;
}
SampleConsumer.prototype._write = function(sample, encoding, next) {
this.count++;
console.log('Hash %d (%s): %s', this.count, sample.passcode, sample.hash);
if (this.count < this.max) {
next();
} else {
return false;
}
};
在这里,我想尽快使用数据,直到达到我的最大样本数,然后结束流。我尝试使用 this.end()
而不是 return false
但这导致了可怕的 write called after end 问题。如果样本量很小,返回 false 确实会停止一切,但当样本量很大时,我会收到内存不足错误:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
Aborted (core dumped)
根据 this SO answer理论上,Write 流将返回 false,导致流缓冲直到缓冲区已满(objectMode
默认为 16),最终 Readable 将调用它是 this.pause()
方法。但是 16 + 16 + 16 = 48
;缓冲区中有 48 个对象,直到内容填满并且系统被阻塞。实际上更少,因为不涉及克隆,所以它们之间传递的对象是相同的引用。这是否意味着内存中只有 16 个对象,直到高水位线停止一切?
最后我意识到我可以让 Writable 引用 Readable 以使用闭包调用它的 pause 方法。然而,这个解决方案意味着 Writable 流知道很多关于另一个对象的信息。我必须传递一个引用:
var foo = new PasscodeGenerator('foobar');
foo
.pipe(new Hasher('md5'))
.pipe(new SampleConsumer(samples, foo));
这感觉不符合流的工作方式。我认为背压足以导致 Writable 阻止 Readable 推送数据并防止内存不足错误。
一个类似的例子是 Unix head
命令。在 Node 中实现它,我会假设目标可以结束,而不仅仅是忽略导致源继续推送数据,即使目标有足够的数据来满足文件的开头部分也是如此。
我如何以惯用的方式构建自定义流,以便在目标准备好结束时源流不会尝试推送更多数据?
最佳答案
这是一个 known issue _read()
是如何在内部被调用的。由于您的 _read()
始终同步/立即推送,因此内部流实现可以在适当的条件下进入循环。 _read()
实现是 generally expected进行某种异步 I/O(例如从磁盘或网络读取)。
解决此问题的方法(如上面的链接中所述)是使您的 _read()
异步至少某些时候。您也可以在每次调用时使其异步:
PasscodeGenerator.prototype._read = function(n) {
var passcode = '' + this.prefix + this.count;
var self = this;
// `setImmediate()` delays the push until the beginning
// of the next tick of the event loop
setImmediate(function() {
self.push({passcode: passcode});
});
this.count++;
};
关于node.js - 如何将背压应用于 Node 流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34226470/
我写了几个命令来转换数据框,但我想将我写的代码简化为四个部分。第 1,2 和 3 部分用于计算第 1、2 和 3 列(计算每列重复值的次数,并完成 0 和三列最大值之间的缺失数)。第四部分是加入前面的
我试图理解应用于函数的类型参数。 我想在下面的方法中使用通用类型,但为了我的理解使用 String 和 Int。 当我如下定义一个函数时 def myfunc[Int](f:String => I
我有一个像下面这样的 DIV: // link to some js .js 在 div 中呈现最新的文章摘要。然而,它在 Calibri
我在 GridView 中有以下列,一列是日期,另一列是美元金额。我应用了格式并将 HtmlEncode 属性设置为 false,但值仍然未格式化: 这就是这些值在 GridView 中的显示方式
假设我已经定义了这些类型: data Km = Km Float deriving (Show, Eq) data Mile = Mile Float deriving (Show, Eq
我有一个关于 value in context 的小问题。 取 Just 'a',所以在这种情况下 Maybe 类型上下文中的值是 'a' 采用[3],因此在这种情况下,[a] 类型上下文中的值为3
require(quantmod) require(PerformanceAnalytics) getSymbols('INTC') x<- monthlyReturn(INTC) rollapply
我正在使用 VBA 对“已应用字轨更改”文档进行更改。 红色段落结束标记是插入段落结束标记。(打开“跟踪更改”> 将光标放在第一段末尾 > 按 Enter > 插入新段落内容 > 格式风格不同) 我需
考虑以下代码: class A{ my_method(const B& b){ import_something_from_c(this, b.getC()); // does some
我正在为自定义 Material 分配图像。分配的图像看起来有点像素化,类似于此图像 我已经将抗锯齿设置为 4 倍。我该如何解决这个问题? 最佳答案 尝试将 Material 的 mipFilter
我将样式应用于 元素和 元素。是否可以在 上使用样式元素应用于 似乎不遵循 CSS 特异性的通常规则。这是真的吗? 示例:http://jsfiddle.net/59dpy/ 尝试将所有背景色设为红
有没有办法将垂直虚线边框应用于 没有他们(边界)合并?我说的是附图上的东西——有 3 个 这里的元素,每个元素包含 2 的。如果我申请 border-right: 1px dashed black到
当我在 CSS 中对主体应用线性渐变时,如下所示 body { background: linear-gradient(#10416b, black); } 它不会将它应用到整个网页,而是将它应用到页
当我将边框和边框半径应用于 td 时,内半径是一个直 Angular ,根本不是圆的。 最佳答案 问题很可能是背景不透明的子元素会剪掉边框的内半径。 要解决此问题,您可以在 td 上应用 overfl
基本上,我有一个小的 SVG,它使用一个组来定义一个可重用的符号。该组包括我想在 CSS 中设置动画的路径。我面临的问题是只有“原始”元素应用了 CSS,“使用过”的元素没有。 .player_arr
宽度属性在这里不起作用: td { height: 50px; width: 25px; border: 1px
我想要一个函数(例如)在两种情况下输出 Map 的所有值: Map map1 = new HashMap(); Map map2 = new HashMap(); output(map1, "1234
我被要求将我们应用中的警报对话框的外观与应用主题使用的外观相匹配。 我设法将样式应用于应用程序中的所有警报对话框,并将其用作应用程序主题的一部分,但有些情况下样式应用不正确。 例如,当警报对话框包含“
我有一个 CGPath(由 UIBezierPath 创建),我想通过应用 CGAffineTransformScale 将其缩放到我想要的任何大小。 这会影响我的绘图质量(在转换为图像时)吗?如果不
您好,我已经在 vector 上使用了一些 STL 算法,例如 find_if、count_if、sort、push_back 等。现在我想为所有容器对象( vector 、列表、映射、集合)制作一个
我是一名优秀的程序员,十分优秀!