-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
abort() - Abort Signal aka break #66
Conversation
- interface, helper function, and BotAction to return a signal for aborting - concept
Codecov Report
@@ Coverage Diff @@
## master #66 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 22 25 +3
Lines 472 538 +66
Branches 106 135 +29
=========================================
+ Hits 472 538 +66
Continue to review full report at Codecov.
|
- given the tight simple use of the helper function and since its unit-tested, we can simply integrate test this botaction
Helper function unit-tested, BotAction integration tested. Didn't unit test the BotAction since by integration testing it with the helper function, and its unit-testing, we have strong coverage for these pieces of code. |
- updated testing to include coverage for new functionality - coverage report was producing a false negative with not covering a partcular branch case (assembledLines > 1) but there is a test for it
- with testing
processAbortSignalReturn function? Something for the repeated code inside the if |
Important to note
All of botmation's core assembly-lines will support this signal with a minor difference in Note, all Utilities use Pipe for assembled BotAction's, therefore will support the AbortLineSignal too Custom assemblers that don't implement the aborting functionality themselves will break the system's flow so a note in future tutorial about building assemblers needs to include a section about the Abort Line Signal |
- adjusted to be chain friendly, as much as possible so they dont look to return a pipe value, but might return an AssemblyLineSignal
The resolving of a ConditionalBotAction in a Utility BotAction has not been setup to abort the botaction if that signal is returned instead of boolean edit: edit2: going to include the conditionalbotaction's as a means to abort to keep things consistent. Adds more work than originally planned, but important to this functionality |
To get around the fact that Utility functions don't return PipeValue's to be chain friendly, in the event that the AbortLineSignal aborts inside a Utility BotAction (assembledLines = 1), then it will go ahead and return the To get around the conflicting types and reduce work, the value is being typed as an AbortLineSignal Not ideal, but works for now. The value is ignored by chain anyway, unless it's an AbortLineSignal so it doesn't break the code but the typing isn't perfect, it's hacky for this piece of functionality when it comes to typing the returned value from these functions when ran inside a pipe versus inside a chain edit: I don't want to detect injects for a pipe to base the return on that, since it hurts the ability to use that BotAction's as a Bot to return a value without manually injecting a pipe object. What I'm doing is, if the types aren't happy because chain doesn't want values that are not typed AbortLineSignal's, then don't worry about it because chain ignores values that are not of that type anyway. The immediate down side is that if a Utility BotAction aborts with one level of assembly with a pipe value, that pipe value will be "typed" as an AbortLineSignal... but since assemblers check the return value anyway with edit2: perfect would be to get rid of chain, or maybe chain doesn't support the AbortLineSignal feature.. but in the end, I believe this solution will suffice |
- conditional handles abort signal - assembled actions handle abort signal - with unit-tests - if you're going to abort in a conditional, versus in assembled of a givenThat, there is a difference in assembly line levels since the conditional is treated like the givenThat botaction but the assembled botaction's ran when the conditional passes is treated as a sub-line
With how the AbortLineSignal is implemented in Utility BotAction's that loop, it's possible to abort a loop iteration, but still continue the loop since each iteration is a sub-line, you can abort 1 assembledLines, so just the loop iteration (the assembled line). If you want too, from an assembled botaction, in a looping utillity botaction, abort out of the loop too, you need to abort by 2, at least (1 for the assembled line, and 1 for the botaction itself, the loop botaction) |
Wondering about a new To catch an "AbortLineSignal" with its edit: edit2: therefore, need 1 more botaction to focus on reverting an abortlinesignal into something more constructive, could abstract it away as some kind of signal receiver which can than operate on it through some kind of cases based on signal types? edit3: edit4: edit5: await recycle('block A')( // recycle will pipe in the value from the AbortLineSignal.pipeValue property
switchPipe('initial-run')(
case('initial-run')(
// initial run that might return an AbortLineSignal
),
abort(), // equivalent to break; - special case when ran inside switchPipe()()
case('abort line signal pipe value when something wasn't found')(
// look somewhere else for it
),
abort(),
// other cases
case()(
// default for unhandled AbortLineSignal.pipeValue cases
)
)
)(page) edit6: await pipe('initial-run')(
recycle('block A')( // recycle will pipe in the value from the AbortLineSignal.pipeValue property
case('initial-run')(
// initial run that might return an AbortLineSignal
// basically the "main" script of the bot that initially runs
// idea is when bot runs into a condition it cannot handle, it can try again differently
// by returning an AbortLineSignal with a pipeValue that matches a case below
),
case('abort line signal pipe value when something wasn't found')(
// look somewhere else for it
// similar to intial run, but slightly different given the pipeValue form the AbortLineSignal
),
// other cases
case()(
// default for unhandled AbortLineSignal.pipeValue cases
// however in this case, it will run after the initial-run too......
)
)
)(page) reminds me of a 🪀 yo-yo edit7: |
- condition and assembled botactions - with unit testing
- in assembly and condition - with unit-testing
- added testing that covers the integration with pipe for handling array of of botactions and unit-tested the single action results handled by pipeActionOrActions - unblocks forAll()() from completion
- chainRunner will return AbortLineSignal.pipeValue when it's the last aborted BotAction line - assemblyLine running a chain will return AbortLineSignal.pipeValue when it's the last aborted Botaction line - chain will not return AbortLineSignal.pipeValue when it's the last aborted botaction in line - this creates a series of steps to shift in functional complexity from chain -> assemblyLine (as chain) -> assembyLine(true) (as pipe) -> pipe - unit-testing
Chains, even if last aborted, will not return ChainRunner will though, it is Assembly Line, if running as a chain, will return Pipe always returns pipeValue, even if empty (then This gives new devs a stepping ladder for embracing these concepts ie: |
Need to update Utilities a bit Decided to go with 2 levels of assembledLines to abort to completely break out of these functions. 1 -> the assembled line itself (maybe iterating in a loop or evaluating the condition/handling the child-line) Therefore it's consistent to break out of utility botaction's level wise, right now breaking out of (1) will break out into the higher-context, skipping (2) The past thinking was the BotAction itself counts as 1 level/1 line, but in reality it's not what's happening. So edit: edit2: edit3: |
forAll()() => 2 levels of assembly (loop iteration, looping) to fully abort These take abort(2) to fully abort, UNLESS the condition itself aborts which only needs 1 to abort That allows the dev to abort() an iteration, but keep the loop going from within a loop iteration, similar to forAll()() except it doesn't evaluate a condition each time that can abort |
- processAbortLineSignal() helper unit-tested - need to update utilities and others to use the helper to reduce testing code
- tests are passing, coverage is passing
Introduced Utilities and Assembly Lines are updated with correct assembly lines aborting (count) and are using |
- it is going to be treated as one assembly line, similar to givenThat - therefore update was small, just return chain resolved result
errors needed a little tweak and inject is fine They are similar to givenThat, where it's 1 line of functionality that its ran, but more similar to an assembler for assembling these actions to run once except with some kind of added unit of functionality Since there is no granular control to gain from requiring 2 lines of assembly to abort an errors or inject, it was left as is |
Kudos, SonarCloud Quality Gate passed! 0 Bugs No Coverage information |
abort example for future docs: await forAll(websites)(
website => ([
goTo(website),
givenThat(websiteIsntVisible(website))(
abort(2) // abort givenThat and the forAll loop iteration for this website, but not the loop
// for the loop, that would take at least 3
)
])
)(mockPage) need a better condition |
For #36 with consideration to #38 & #61
Break is a reserved keyword, so went with
abort()
This BotAction returns a signal to be processed by its assembler. The purpose is to inform the assembler that it needs to stop running its assembled BotAction's and possibly return a Signal (with
assembledLines
decreased by 1 count) so the higher-order assembler can abort and follow through so anywhere in the program, or fully abort with (assembledLines
set to 0)abort()
BotAction to use this feature, you simply need to return an AbortLineSignal, so an example in the docs of a forAll() which uses custom BotAction's that check websites for things and aborts if they don't meet some criteria (1 line of aborting), which won't break the loop but the one loop line of assembly for the specific loop iterationTo be included in next minor release v2.1.0