CAPL block node from sending messages - can-bus

I have a CAPL file attached to a CAN node that periodically sends a message using the 'output' function. How can I use a second CAPL file to block the node sending the message (while doing everything that the node does) ?

You can add an output filter to your node, as shown below, to block the messages.

You can create a sysvar in your simulation, which will be used as a switch in your simulated *.can Network node.
You just have to condition the output code to the value of the system variable you created.
if (Sysvar_SimEnabled)
{
output(message);
output(message1);
output(message3);
}
This Sysvar_SimEnabled will be a global variable, thus can be set to any value from another *.can CAPL Network node.

You can stop all your cyclic messages, by canceling timers of Each message
Example:
message can1.0x12 message1;
msTimer tmessage1;
on timer tmessage1
{
output(message1); // sending message
setTimer(tmessage1,100); // set the cyclic time as 100ms
}
on envVar envmessage1
{
if (getValue(envmessage1) == 1)
{
setTimer(tmessage1,100); // set and start the cyclic time as 100ms
}
else
{
cancelTimer(tmessage1); // cancel the cyclic timer
}
}
if you just do envmessage1 = 0 in another node, it will stop the message, like the same for all messages, have to write environment variable, then you can control other Node messages.

Related

Reactor. List of Monos, retry on fail

I have list List<Mono<String>>. Each Mono represents API call where I wait on I/O for result. The problem is that some times some calls return nothing (empty String), and I need repeat them again on that case.
Now it looks like this:
val firstAskForItemsRetrieved = firstAskForItems.map {
it["statistic"] = (it["statistic"] as Mono<Map<Any, Any>>).block()
it
}
I'm waiting for all Monos to finish, then in case of empty body I repeat request
val secondAskForItem = firstAskForItemsRetrieved
.map {
if ((it["statistic"] as Map<Any, Any>).isEmpty()) {
// repeat request
it["statistic"] = getUserItem(userName) // return Mono
} else
it["statistic"] = Mono.just(it["statistic"])
it
}
And then block on each item again
val secondAskForItemsRetrieved = secondAskForItems.map {
it["statistic"] = (it["statistic"] as Mono<Map<Any, Any>>).block()
it
}
I see that looks ugly
Are any other ways to retry call in Mono if it fails, without doing it manually?
Is it block on each item a right way to get them all?
How to make the code better?
Thank you.
There are 2 operators I believe can help your:
For the "wait for all Mono" use case, have a look at the static methods when and zip.
when just cares about completion, so even if the monos are empty it will just signal an onComplete whenever all of the monos have finished. You don't get the data however.
zip cares about the values and expects all Monos to be valued. When all Monos are valued, it combines their values according to the passed Function. Otherwise it just completes empty.
To retry the empty Monos, have a look at repeatWhenEmpty. It resubscribes to an empty Mono, so if that Mono is "cold" it would restart the source (eg. make another HTTP request).

CAPL Scripting - CAN C communication (Stop transmitting one message from DBC)

I am working on a CAPL script that has to allow all messages to transmit on a CAN C channel and stop transmitting one particular message from the database file.
Can anyone help with the method/function/code I can use?
Your question is vague, but I'm assuming you are going from one CAN channel to another. For instance, CAN C to CAN D (or CAN 3 to CAN 4), than you could do:
on message CAN3.0x7FF // This would be that one ID that stops at some point
{
message CAN4.0x7FF msg;
msg = this;
// Assuming you are receiving on CAN 3, and looking to transmit on CAN 4
if(this.dir == rx)
{
// Declare a global variable that sets to 1 when you want it to stop
if(MSG_STOP == 0)
output(msg);
}
}
on message CAN3.*
{
message CAN4.* msg;
msg = this;
if (this.dir == rx)
{
output (msg);
}
}
AFAIK, the only way to accomplish this is to disable any automatic transmission of messages (e.g. via the IG or Network IL) and transmit all messages manually from your CAPL script in timer callbacks. Transmission can be done using the output function and based on whichever criteria you define, you can choose not to call output for any messages which should be blocked.
If you are using the Interaction Layer (IL) in your simulation, and the DBC file cyclic times are correctly configured there are some CAPL functions that can be used for fault injection which will allow you to selectively start/stop transmitting certain messages:
on sysvar Sys_m0x461_Send {
/**********************************************************
* FAULT INJECTION Enable/Disable Msg Sending
**********************************************************/
if (#this) {
ILFaultInjectionEnableMsg(Message0x461fromDBC);
}
else {
ILFaultInjectionDisableMsg(Message0x461fromDBC);
}
}
In the example if the system variable (could be linked to a panel control, e.g. checkbox) equals '1' the message will transmit as defined in the DBC, otherwise the message sending is stopped.

Memory leak of AKKA Actor

I have a simple test program to try ...
object ActorLeak extends App {
val system = ActorSystem("ActorLeak")
val times = 100000000
for (i <- 1 to times) {
val myActor = system.actorOf(Props(classOf[TryActor], i), name = s"TryActor-$i")
//Thread sleep 100
myActor ! StopCmd
if (i % 10000 == 0)
println(s"Completed $i")
}
println(s"Creating and stopping $times end.")
val hookThread = new Thread(new Runnable {
def run() {
system.shutdown()
}
})
Runtime.getRuntime.addShutdownHook(hookThread)
}
case object StopCmd
class TryActor(no: Int) extends Actor {
def receive = {
case StopCmd => context stop self
}
}
I found: sometime OutOfMemoryError, sometimes make JVM die, run slowly slowly ...
Is there memory leak in creation / stop of actors?
Actor creation and messaging are both asynchronous, when actorOf returns this does not mean the actor has been created yet, and when ! returns it does not mean the actor has received or acted upon the message.
This means that you are actually not creating and stopping an actor for each iteration, but that you trigger creation, and send a message, this loop is probably quicker in queueing up actor creation than the messages can arrive and trigger the stopping of the messages which fills up the heap of your JVM.
To do what you I think you are trying to do you would have to provide a response from the actor upon receiving the StopCmd and wait for that inside of your loop before continuing with the next iteration. This can be done with the ask pattern together with Await.result to block the main thread until the actor reply has returned.
Note that this is only useful for your understanding and not something that you would do in an actual system using Akka.

include downstream/child Jenkins job's console output into triggering job's console output

2 Jenkins jobs: A and B.
A triggers B as blocking build step ("Block until the triggered projects finish their builds"). Is there a way to include B's console output into A's console output?
Motivation: for browser use of Jenkins A's console output contains a link to B's console output which is fine. But when using Jenkins via command line tools (jenkins-cli) there's no quick and easy way to see B's console output.
Any ideas?
Interesting. I'd try something like this.
From http://jenkinsurl/job/jobname/lastBuild/api/
Accessing Progressive Console Output
You can retrieve in-progress console output by making repeated GET requests with a parameter. You'll basically send GET request to this URL (or this URL if you want HTML that can be put into tag.) The start parameter controls the byte offset of where you start.
The response will contain a chunk of the console output, as well as the X-Text-Size header that represents the bytes offset (of the raw log file). This is the number you want to use as the start parameter for the next call.
If the response also contains the X-More-Data: true header, the server is indicating that the build is in progress, and you need to repeat the request after some delay. The Jenkins UI waits 5 seconds before making the next call. When this header is not present, you know that you've retrieved all the data and the build is complete.
So you can trigger a downstream job, but don't "block until downstream completes". Instead, add an extra step (execute shell, probably) and write a script that will read the console output of the other job as indicated above, and display it in console output of current job. You will have to detect when the child job finished by looking for X-More-Data: true header, as detailed above.
I know this is an old question, but i had to this myself recently. I figure this would help someone else looking to do the same. Here's a Groovy script that will read a given job's progressiveText URL. The code is written in such a way that it should be plug and play. Make sure to set the jenkinsBase and jobName first. The approach is no different to what has already been mentioned.
Here's a short set of instructions on how to use this: (1) Configure downstream job so that anonymous users hasRead and ViewStatus rights. (2) In the upstream job, create a Trigger/call builds on other projects step that will call the downstream job. (3) Do not check the "Block until the triggered projects finish their builds. (4) Right after that step, create an Execute Groovy script step and paste the following code:
def jenkinsBase = // Set to Jenkins base URL here
def jobName = // Set to jenkins job name
def jobNumber = 'lastBuild' // Tail last build
def address = null
def response = null
def start = 0 // Start at offset 0
def cont = true // This semaphore holds the value of X-More-Data header value
try {
while (cont == true) { // Loop while X-More-Data value is equal to true
address = "${jenkinsBase}/job/${jobName}/${jobNumber}/logText/progressiveText?start=${start}"
def urlInfo = address.toURL()
response = urlInfo.openConnection()
if (response.getResponseCode() != 200) {
throw new Exception("Unable to connect to " + address) // Throw an exception to get out of loop if response is anything but 200
}
if (start != response.getHeaderField('X-Text-Size')) { // Print content if the starting offset is not equal the value of X-Text-Size header
response.getInputStream().getText().eachLine { line ->
println(line)
}
}
start = response.getHeaderField('X-Text-Size') // Set new start offset to next byte
cont = response.getHeaderField('X-More-Data') // Set semaphore to value of X-More-Data field. If this is anything but true, we will fall out of while loop
sleep(3000) // wait for 3 seconds
}
}
catch (Exception ex) {
println (ex.getMessage())
}
This script can be further improved by programatically getting the downstream job number.
There is also a Python version of this approach here.

Inet framework: Send message from one host to another

I am new to Omnet++ and I am trying to simulate a Wifi network. I have successfully created a network consisting of an AP and some nodes and all the nodes are able to connect to the AP.
What I want to do is that once all the nodes are connected to the AP, a node (based on its IP address) should send a message to another node in the network. I have created the .msg file with all the required fields and it is successfully compiled by the message compiler to the corresponding _m.h and _m.cc files. I want this message to be sent to the other node.
How to proceed with this? Iknow it has to do something with the handleMessage() function but I can't find the file containing that function.
Thanks in advance for any kind of help.
To send the initial message you will have to use the send() when you initialize you node.
From the tictoc tutorial:
void Txc1::initialize()
{
// Initialize is called at the beginning of the simulation.
// To bootstrap the tic-toc-tic-toc process, one of the modules needs
// to send the first message. Let this be `tic'.
// Am I Tic or Toc?
if (strcmp("tic", getName()) == 0)
{
// create and send first message on gate "out". "tictocMsg" is an
// arbitrary string which will be the name of the message object.
cMessage *msg = new cMessage("tictocMsg");
send(msg, "out");
}
}
Then you want the nodes to be able to react. Their reaction can be silent -- just accept the message and delete it, or send another message in return.
For that you will need to implement the handleMessage() function inside the nodes .cc file.
void Txc1::handleMessage(cMessage *msg)
{
// The handleMessage() method is called whenever a message arrives
// at the module. Here, we just send it to the other module, through
// gate `out'. Because both `tic' and `toc' does the same, the message
// will bounce between the two.
send(msg, "out");
}
You can find the function in the .cc file in the same project or folder. Normally the name of the .cc file is close to the name of the .ned file that caries the details of the host or node or whatever you call it in your project.

Resources