1

在 NoFlo 中,我经常遇到这样的组件:

noflo = require 'noflo'

class Foo extends noflo.AsyncComponent
  constructor: ->
    @inPorts = new noflo.InPorts
      main:
        datatype: 'int'
        description: 'Main async input'
        required: true
      sup1:
        datatype: 'string'
        description: 'Supplementary input #1'
        required: true
      sup2:
        datatype: 'int'
        description: 'Supplementary input #2'
        required: true
    @outPorts = new noflo.OutPorts
      out:
        datatype: 'object'
        description: 'Result object'
      error:
        datatype: 'object'

    @sup1 = null
    @sup2 = null

    @inPorts.sup1.on 'data', (@sup1) =>
    @inPorts.sup2.on 'data', (@sup2) =>

    super 'main', 'out'

  doAsync: (main, callback) ->
    unless @sup1 and @sup2
      return callback new Error "Supplementary data missing"

    # Combine data received from different sources
    result =
      main: main
      sup1: @sup1
      sup2: @sup2

    # Reset state until next iteration
    @sup1 = null
    @sup2 = null

    # Send the result
    @outPorts.out.send result
    @outPorts.out.disconnect()

    callback()

exports.getComponent = -> new Foo

它假设所有 3 个输入连接都以某种方式同步,尽管网络主要由异步组件组成。考虑这种情况:Foo等待main到来并接收sup1数据sup2包,但随后下一个sup1数据包到达,应该与 next 结合main,同时仍在等待上一个数据包main的到来。结果将是更多或更高数据吞吐量的完全混乱。

NoFlo 异步组件是否有任何数据竞争保护手段,还是完全取决于组件设计者?

这里有两个问题:同步输入和维护内部状态。内部状态或多或少受到 Node.js 不是多线程的事实的保护,并且在前一个doAsync()处理程序完成之前没有任何东西会尝试访问状态变量。但是同步输入仍然是一个问题。

4

2 回答 2

0

对于最新版本的 NoFlo,推荐的方法是使用 noflo.helpers.WirePattern,并使用组进行同步。

于 2014-11-24T17:45:32.557 回答
0

事实证明,NoFlo v0.5.1 没有针对数据竞争的内置辅助工具,组件设计人员必须自己关心它。

对于异步组件,这意味着:

  1. 如果需要来自多个输入端口的数据,请确保它在处理之前从所有端口到达。请参阅组件和端口工具箱
  2. 从迭代到迭代重置组件的状态,以确保不会发生“记忆”副作用。
  3. 通过在组件前面添加一个 Throttle 组件并将组件的 LOAD 输出端口与 Throttle 的 LOAD 输入端口连接,保护组件的内部状态免受数据竞争的影响。
于 2014-05-20T17:50:25.427 回答