Skip to content

Commit

Permalink
fix(core): session call out actions after handler actions
Browse files Browse the repository at this point in the history
  • Loading branch information
wdavidw committed Feb 26, 2021
1 parent 2635719 commit a72a8d6
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 10 deletions.
19 changes: 17 additions & 2 deletions packages/core/lib/session.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions packages/core/src/session.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ session = (action={}) ->
name: 'nikita:register'
args: name: name, action: act
# Local scheduler to execute children and be notified on finish
action.scheduler = schedule()
schedulers =
in: schedule()
out: schedule null, pause: true
# Start with a paused scheduler to register actions out of the handler
action.scheduler = schedulers.out
# Expose the action context
action.config.context = action.context if action.context
action.context = new Proxy on_call, get: on_get
Expand All @@ -85,6 +89,8 @@ session = (action={}) ->
# Merge the registry action with the user action properties
for k, v of action_from_registry
action[k] = merge action_from_registry[k], action[k]
# Switch the scheduler to register actions inside the handler
action.scheduler = schedulers.in
# Hook attended to alter the execution of an action handler
output = action.plugins.call
name: 'nikita:action'
Expand All @@ -94,7 +100,11 @@ session = (action={}) ->
# Execution of an action handler
action.handler.call action.context, action
# Ensure child actions are executed
pump = -> action.scheduler.pump()
pump = ->
# Now that the handler has been executed,
# import all the actions registered outside of it
action.scheduler.state.stack.push child while child = schedulers.out.state.stack.shift()
action.scheduler.pump()
output.then pump, pump
# Make sure the promise is resolved after the scheduler and its children
Promise.all [output, action.scheduler]
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/actions/execute/index.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe 'actions.execute', ->
false.should.be.true()
await nikita
ssh: ssh
, ->
, (->)
.execute
command: "cat #{__filename} | grep #{search1}"
stdout: out
Expand Down
78 changes: 76 additions & 2 deletions packages/core/test/session/creation.coffee
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

nikita = require '../../src'
session = require '../../src/session'

describe 'session.creation', ->
Expand All @@ -7,8 +8,14 @@ describe 'session.creation', ->

it 'which succeed', ->
result = await session [
-> 1
-> 2
-> new Promise (resolve) ->
setTimeout ->
resolve 1
, 100
-> new Promise (resolve) ->
setTimeout ->
resolve 2
, 10
]
result.should.eql [1, 2]

Expand All @@ -18,3 +25,70 @@ describe 'session.creation', ->
-> true
]
.should.be.rejectedWith 'Catchme'

describe 'flow with external action', ->

it 'plugin and handler and no external action', ->
# No external action but we use it as a reference
stack = []
await nikita
hooks: on_action: (action)->
new Promise (resolve) ->
setTimeout ->
stack.push 'plugin'
resolve()
, 100
, ->
@call ({metadata}) ->
stack.push metadata.position.join ':'
@call ({metadata}) ->
stack.push metadata.position.join ':'
stack.should.eql ['plugin', '0:0', '0:1']

it 'after no plugin and no handler but a property object', ->
stack = []
await nikita
key: 'value'
.call ({metadata}) ->
stack.push metadata.position.join ':'
.call ({metadata}) ->
stack.push metadata.position.join ':'
stack.should.eql ['0:0', '0:1']

it 'after plugin', ->
stack = []
await nikita
hooks: on_action: (action)->
new Promise (resolve) ->
setTimeout ->
stack.push 'plugin'
resolve()
, 100
.call ({metadata}) ->
stack.push metadata.position.join ':'
.call ({metadata}) ->
stack.push metadata.position.join ':'
stack.should.eql ['plugin', '0:0', '0:1']

it 'after plugin and handler', ->
stack = []
await nikita
hooks: on_action: (action) ->
new Promise (resolve) ->
setTimeout ->
stack.push 'plugin'
resolve()
, 100
, ({metadata}) ->
@call ({metadata}) ->
new Promise (resolve) ->
setTimeout ->
stack.push metadata.position.join ':'
resolve()
, 100
.call ({metadata}) ->
stack.push metadata.position.join ':'
.call ({metadata}) ->
stack.push metadata.position.join ':'
stack.should.eql ['plugin', '0:0', '0:1', '0:2']

6 changes: 3 additions & 3 deletions packages/core/test/session/plugins/session.resolved.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ describe 'session.plugins.session.resolved', ->
n.call ->
stack.push '3'
await n
# Not sure if we really expect 3 to be called before 1 and 2, what's
# important in the context of this test is how 'end' is called last
# what's important in the context of this test is how 'end' is called last
# however, we also indirectly test action in handler being called after external actions
stack.should.eql [
'3'
'1'
'2'
'3'
'end'
]

0 comments on commit a72a8d6

Please sign in to comment.