NoFlo异步组件和数据竞争

时间:2014-05-14 08:46:53

标签: asynchronous noflo

在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来接收sup1sup2个数据包,然后下一个sup1数据包到达,应该与下一个{ {1}},同时仍在等待之前的main。结果将是更多或更高数据吞吐量的完全混乱。

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

问题有两个方面:同步输入和维持内部状态。内部状态或多或少受到保护,因为Node.js不是多线程的,在前一个main处理程序完成之前,没有任何东西会尝试访问状态变量。但同步输入仍然是一个问题。

2 个答案:

答案 0 :(得分:0)

正如NoFlo v0.5.1所示,没有针对数据竞赛的内置辅助工具,组件设计人员必须自己关心它。

对于异步组件,意味着:

  1. 如果需要来自多个输入的数据,请确保在处理之前从所有端口到达。见Components & Ports toolbox
  2. 将组件的状态从迭代重置为迭代,以确保没有"内存"副作用发生。
  3. 保护组件的内部状态免受数据竞争的影响,方法是将其与Throttle组件对齐,并将组件的LOAD输出连接到Throttle的LOAD inport。

答案 1 :(得分:0)

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