Is it possible to sleep inside a Future in Scala.js ?
Something like:
Future {
Thread.sleep(1000)
println("ready")
}
If I try this then I get an exception saying that sleep method does not exist.
It seems like that it is possible to sleep in JS : What is the JavaScript version of sleep()? even though it is not possible to block.
You cannot really pause in the middle of the future body, but you can register your future as a followup to a "delay" Future, which you can define as:
def delay(milliseconds: Int): Future[Unit] = {
val p = Promise[Unit]()
js.timers.setTimeout(milliseconds) {
p.success(())
}
p.future
}
and which you can then use as:
val readyLater = for {
delayed <- delay(1000)
} yield {
println("ready")
}
Related
I am having some issues trying to solve this problem. What I'd like to happen is if the forEach loop does NOT find the first text after running through all the cells. Then the final if block on the outside should run, and assert that the first text cell was not found.
Thank you :-)
Cypress.Commands.add("aCommand", (Locator, firstCellText, secondCellText) => {
let firstCellTextFound = false
cy.get("aDifferentLocator").find(Locator).each($cell => {
let text = $cell.text()
if (text.includes(firstCellText)) {
cy.wrap($cell).next().should("have.text", secondCellText)
firstCellTextFound = true
}
})
if(firstCellTextFound == false)
{
expect(firstCellTextFound).to.be.true
}
})
Your outside if block is synchronous code, while your cy.get() command is asynchronous, so the if block will execute while the cy.get().each() is still running. Wrapping that final if in a .then() block should solve your problem.
let firstCellTextFound = false
cy.get("aDifferentLocator").find(Locator).each($cell => {
... code ...
}).then(() => {
if(firstCellTextFound == false) {
expect(firstCellTextFound).to.be.true
}
})
I built a simple plugin that shows in the CRMContainer the url of my CRM given some attributes parameters (if they are passed by), during inbound tasks this works fine, but the problem is that during outbound calls the behaviour is not the one expected, this is the piece of code:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
return task
? `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`
: 'https://mycrm.zzz/contacts/';
}
}
I would need an additional condition that tells the code, if this is an outbound voice call to always show a default url.
I tried adding an if/else that checks if task.attributes.direction is outbound, but Flex says this is undefined.
Any tip?
Thanks
Max
The problem is that you aren't checking for the existence of the task. Your original code had this:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
return task
? `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`
: 'https://mycrm.zzz/contacts/';
}
}
Which returns the URL with the task attributes in it only if the task exists, because of the ternary conditional.
So, when you try to use the attributes you need to make sure the task exists. So taking your code from the last comment, it should look like this:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
if (task) {
if (task.attributes.direction === 'outbound'){
return `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`;
} else {
return `https://mycrm.zzz/contacts/`
}
} else {
return 'https://mycrm.zzz/contacts/';
}
}
We have a Jenkins pipeline script that requests approval from the user after all the preparatory steps are complete, before it actually applies the changes.
We want to add a timeout to this step, so that if there is no input from the user then the build is aborted, and are currently working on using this kind of method:
try {
timeout(time: 30, unit: 'SECONDS') {
userInput = input("Apply changes?")
}
} catch(err) {
def user = err.getCauses()[0].getUser()
if (user.toString == 'SYSTEM') { // if it's system it's a timeout
didTimeout = true
echo "Build timed out at approval step"
} else if (userInput == false) { // if not and input is false it's the user
echo "Build aborted by: [${user}]"
}
}
This code is based on examples found here: https://support.cloudbees.com/hc/en-us/articles/226554067-Pipeline-How-to-add-an-input-step-with-timeout-that-continues-if-timeout-is-reached-using-a-default-value and other places online, but I really dislike catching all errors then working out what's caused the exception using err.getCauses()[0].getUser(). I'd rather explicitly catch(TimeoutException) or something like that.
So my question is, what are the actual exceptions that would be thrown by either the approval step timing out or the userInput being false? I haven't been able to find anything in the docs or Jenkins codebase so far about this.
The exception class they are referring to is org.jenkinsci.plugins.workflow.steps.FlowInterruptedException.
Cannot believe that this is an example provided by CloudBeeds.
Most (or probably all?) other exceptions won't even have the getCauses() method which of course would throw another exception then from within the catch block.
Furthermore as you already mentioned it is not a good idea to just catch all exceptions.
Edit:
By the way: Scrolling further down that post - in the comments - there you'll find an example catching a FlowInterruptedException.
Rather old topic, but it helped me, and I've done some more research on it.
As I figured out, FlowInterruptedException's getCauses()[0] has .getUser() only when class of getCauses()[0] is org.jenkinsci.plugins.workflow.support.steps.input.Rejection. It is so only when timeout occured while input was active. But, if timeout occured not in input, getCause()[0] will contain object of another class: org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout (directly mentioning timeout).
So, I end up with this:
def is_interrupted_by_timeout(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e, Boolean throw_again=true) {
// if cause is not determined, re-throw exception
try {
def cause = e.getCauses()[0]
def cause_class = cause.getClass()
//echo("cause ${cause} class: ${cause_class}")
if( cause_class == org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout ) {
// strong detection
return true
} else if( cause_class == org.jenkinsci.plugins.workflow.support.steps.input.Rejection ) {
// indirect detection
def user = cause.getUser()
if( user.toString().equals('SYSTEM') ) {
return true
} else {
return false
}
}
} catch(org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException e_access) {
// here, we may deal with situation when restricted methods are not approved:
// show message and Jengins' admin will copy/paste and execute them only once per Jenkins installation.
error('''
To run this job, Jenkins admin needs to approve some Java methods.
There are two possible ways to do this:
1. (better) run this code in Jenkins Console (URL: /script):
import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval;
def scriptApproval = ScriptApproval.get()
scriptApproval.approveSignature('method org.jenkinsci.plugins.workflow.steps.FlowInterruptedException getCauses')
scriptApproval.approveSignature('method org.jenkinsci.plugins.workflow.support.steps.input.Rejection getUser')
scriptApproval.save()
'''.stripIndent())
return null
}
if( throw_again ) {
throw e
} else {
return null
}
}
And now, you may catch it with something like this:
try {
...
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException err) {
if( is_interrupted_by_timeout(err) ) {
echo('It is timeout!')
}
}
P.S. I agree, this is bad Jenkins design.
All,
Here is a unit test for checking the size of a collection
main() {
test("Resource Manager Image Load", () {
ResourceManager rm = new ResourceManager();
int WRONG_SIZE = 1000000;
rm.loadImageManifest("data/rm/test_images.yaml").then((_){
print("Length="+ rm.images.length.toString()); // PRINTS '6' - WHICH IS CORRECT
expect(rm.images, hasLength(WRONG_SIZE));
});
});
}
I am running this from a browser (client-side Dart libraries are in use) and it ALWAYS passes, no matter what the value of WRONG_SIZE.
Help appreciated.
In such simple cases you can just return the future. The unit test framework recognizes it and waits for the future to complete. This also works for setUp/tearDown.
main() {
test("Resource Manager Image Load", () {
ResourceManager rm = new ResourceManager();
int WRONG_SIZE = 1000000;
return rm.loadImageManifest("data/rm/test_images.yaml").then((_) {
//^^^^
print("Length="+ rm.images.length.toString()); // PRINTS '6' - WHICH IS CORRECT
expect(rm.images, hasLength(WRONG_SIZE));
});
});
}
The problem is that your code returns a Future, and your test completes before the code in the Future has finished, so there's nothing to cause it to fail.
Check out the Asynchronous Tests section on the Dart site. There are methods like expectAsync that allow the future to be passed to the test framework so that it can wait for them to complete and handle the result correctly.
Here's an example (note the expect call is now inside the function passed to expectAsync)
test('callback is executed once', () {
// wrap the callback of an asynchronous call with [expectAsync] if
// the callback takes 0 arguments...
var timer = Timer.run(expectAsync(() {
int x = 2 + 3;
expect(x, equals(5));
}));
});
I am trying to build a safety that will check for a condition that will either be true or false. This will be called multiple times through out a long bit of code. if the condition is true it will cause the rest of the code to stop. I cant seem to figure it out. Can someone point me in the right direction? By the way Exit will not work as it will close the whole program that I use.
proc _CheckEsc {} {
if {condition is true} {
return
}
return
}
proc testType {} {
set TestResult 0
while {$TestResult < 10} {
_CheckEsc;
incr TestResult
}
return;
}
You can make _CheckEsc stop it's caller by using some of the more advanced features of return. In particular, we can use it to make _CheckEsc act itself like a break or a return.
This mechanism is very much like throwing an exception in other languages (and in fact you can regard Tcl as having special exception classes for return, break and continue, except things are rather more complicated than that under the covers).
Making the caller's loop stop
proc _CheckEsc {} {
if {condition is true} {
return -code break
}
}
Making the caller return
proc _CheckEsc {} {
if {condition is true} {
return -level 2
# Or, if you want to return a value from the caller:
### return -level 2 "the value to return"
}
}
Note that the -level option isn't supported in Tcl 8.4 and before; that limits what you can do with it, but your use case works provided you do this instead:
proc _CheckEsc {} {
if {condition is true} {
return -code return
# Or, if you want to return a value from the caller:
### return -code return "the value to return"
}
}
Will something like this works for you?
proc _CheckEsc {} {
return {condition is true}; # I don't know what you have here
}
proc testType {} {
set TestResult 0
while {_CheckEsc && $TestResult < 10} {
incr TestResult
}
}
You can help us out by being more specific of what _CheckEsc does.