Skip to content

Commit

Permalink
Updated GroupComponent helper:
Browse files Browse the repository at this point in the history
 - Added support for async components (via config and callback in handler's params)
 - Matching inputs by group name is disabled by default, because it conflicts with other grouping conventions
  • Loading branch information
trustmaster committed May 23, 2014
1 parent 26375fb commit 00f4be4
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 9 deletions.
41 changes: 38 additions & 3 deletions spec/Helpers.coffee
Expand Up @@ -97,7 +97,7 @@ describe 'Component traits', ->
chai.expect(data).to.deep.equal src[groups[0]]
out.send data
# done() if groups[0] is 333
, ['x', 'y', 'z'], 'point'
, ['x', 'y', 'z'], 'point', {group: true}

groups = []
count = 0
Expand Down Expand Up @@ -142,7 +142,7 @@ describe 'Component traits', ->
z.send 789
z.disconnect()

it 'should process inputs for different groups independently', (done) ->
it 'should process inputs for different groups independently with group: true', (done) ->
src =
1: {x: 1, y: 2, z: 3}
2: {x: 4, y: 5, z: 6}
Expand All @@ -162,7 +162,7 @@ describe 'Component traits', ->

helpers.GroupComponent c, (data, groups, out) ->
out.send {x: data.x, y: data.y, z: data.z}
, ['x', 'y', 'z'], 'point'
, ['x', 'y', 'z'], 'point', {group: true}

groups = []

Expand Down Expand Up @@ -190,3 +190,38 @@ describe 'Component traits', ->
input.send src[tuple[0]][tuple[1]]
input.endGroup()
input.disconnect()

it 'should support asynchronous handlers', (done) ->
point =
x: 123
y: 456
z: 789

helpers.GroupComponent c, (data, groups, out, callback) ->
setTimeout ->
out.send {x: data.x, y: data.y, z: data.z}
callback()
, 100
, ['x', 'y', 'z'], 'point', {async: true, group: true}

p.removeAllListeners()
counter = 0
p.on 'begingroup', (grp) ->
counter++
p.on 'endgroup', ->
counter--
p.once 'data', (data) ->
chai.expect(data).to.deep.equal point
p.once 'disconnect', ->
chai.expect(counter).to.equal 0
done()

x.beginGroup 'async'
y.beginGroup 'async'
z.beginGroup 'async'
x.send point.x
y.send point.y
z.send point.z
x.endGroup()
y.endGroup()
z.endGroup()
28 changes: 22 additions & 6 deletions src/lib/Helpers.coffee
Expand Up @@ -28,6 +28,10 @@ exports.MapComponent = (component, func, config) ->
exports.GroupComponent = (component, func, inPorts='in', outPort='out', config={}) ->
unless Object.prototype.toString.call(inPorts) is '[object Array]'
inPorts = [inPorts]
# For async func
config.async = false unless 'async' of config
# Group requests by group ID
config.group = false unless 'group' of config

for name in inPorts
unless component.inPorts[name]
Expand All @@ -48,15 +52,27 @@ exports.GroupComponent = (component, func, inPorts='in', outPort='out', config={
when 'begingroup'
inPort.groups.push payload
when 'data'
key = inPort.groups.toString()
key = if config.group then inPort.groups.toString() else ''
groupedData[key] = {} unless key of groupedData
groupedData[key][port] = payload
# Flush the data if the tuple is complete
if Object.keys(groupedData[key]).length is inPorts.length
out.beginGroup group for group in inPort.groups
func groupedData[key], inPort.groups, out
out.endGroup() for group in inPort.groups
out.disconnect()
delete groupedData[key]
groups = inPort.groups
out.beginGroup group for group in groups
if config.async
grps = groups.slice(0)
func groupedData[key], groups, out, (err) ->
if err
component.error err, groups
# For use with MultiError trait
component.fail if typeof component.fail is 'function'
out.endGroup() for group in grps
out.disconnect()
delete groupedData[key]
else
func groupedData[key], inPort.groups, out
out.endGroup() for group in inPort.groups
out.disconnect()
delete groupedData[key]
when 'endgroup'
inPort.groups.pop()

0 comments on commit 00f4be4

Please sign in to comment.