noflo
Version:
Flow-Based Programming environment for JavaScript
119 lines (101 loc) • 3.84 kB
text/coffeescript
# NoFlo - Flow-Based Programming for JavaScript
# (c) 2013-2017 Flowhub UG
# (c) 2011-2012 Henri Bergius, Nemein
# NoFlo may be freely distributed under the MIT license
#
# Baseclass for components dealing with asynchronous I/O operations. Supports
# throttling.
port = require "./Port"
component = require "./Component"
platform = require './Platform'
class AsyncComponent extends component.Component
constructor: (="in", ="out", ="error") ->
platform.deprecated 'noflo.AsyncComponent is deprecated. Please port to Process API'
unless []
throw new Error "no inPort named '#{@inPortName}'"
unless []
throw new Error "no outPort named '#{@outPortName}'"
= 0
= []
= []
.load = new port.Port()
[].on "begingroup", (group) =>
return .push { name: "begingroup", data: group } if > 0
.push group
[].beginGroup group
[].on "endgroup", =>
return .push { name: "endgroup" } if > 0
.pop()
[].endGroup()
[].on "disconnect", =>
return .push { name: "disconnect" } if > 0
[].disconnect()
= []
.load.disconnect() if .load.isAttached()
[].on "data", (data) =>
return .push { name: "data", data: data } if .length > 0
data
processData: (data) ->
data, (err) =>
err, , if err
incrementLoad: ->
++
.load.send if .load.isAttached()
.load.disconnect() if .load.isAttached()
doAsync: (data, callback) ->
callback new Error "AsyncComponents must implement doAsync"
decrementLoad: ->
throw new Error "load cannot be negative" if == 0
--
.load.send if .load.isAttached()
.load.disconnect() if .load.isAttached()
if typeof process isnt 'undefined' and process.execPath and process.execPath.indexOf('node') isnt -1
# nextTick is faster than setTimeout on Node.js
process.nextTick =>
else
setTimeout =>
do
, 0
processQueue: ->
if > 0
return
processedData = false
while .length > 0
event = [0]
switch event.name
when "begingroup"
return if processedData
[].beginGroup event.data
.push event.data
.shift()
when "endgroup"
return if processedData
[].endGroup()
.pop()
.shift()
when "disconnect"
return if processedData
[].disconnect()
.load.disconnect() if .load.isAttached()
= []
.shift()
when "data"
event.data
.shift()
processedData = true
tearDown: (callback) ->
= []
= []
do callback
# Old-style error function because of legacy ports
error: (e, groups = [], errorPort = 'error') =>
if [errorPort] and ([errorPort].isAttached() or not [errorPort].isRequired())
[errorPort].beginGroup group for group in groups
[errorPort].send e
[errorPort].endGroup() for group in groups
[errorPort].disconnect()
return
throw e
exports.AsyncComponent = AsyncComponent