I want to store process times in my model for each agent of type Box. For this purpose I have created a Java class ProcessData.
My problem is that I always get NullPointerExceptions. I don't know if it's because of my code or the functionality of the batch block.
When the wait block reaches a certain size, all agents of type Box are routed to the batch block. The batch agent then waits in the seize block for staff member. If the agent is then seized, each agent of type Box contained in the batch agent should then get a start processing time. This is my code at enter of the delay block: box.getProcessData().add(new ProcessData(date(), duration()));. Using a constructor, I add the start time and duration as new variables to a new ProcessData entry.
To determine the end time of each Box agent I have the following code at unbatch block entry: box.getProcessData().getLast().setEnd(date());
Since I have a NullPointerException I can't tell exactly where it came from. My guess is that I have a bug with addressing the code: should I use agent. (from batch) or box. (name of original agent before batch)? Or is it not possible to give the batch agent properties that are inherited by the box agent?
First error is at unbatch, so the second code from above and second error is the following public void onExit( Box batch, Box agent ) { _unbatch_onExit_xjal( this, batch, agent ); }.
Following the screenshot of my error:
The problem you have with this model first,is that you are seizing a resource for the batch without releasing that resource... you need to release before unbatch
your error nevertheless is related to some code that you wrote in the on exit action of the unbatch block that you are unfortunately not telling us
But to discover what is null, check with a traceln() the value of the variables that are present in the on exit section of the unbatch in order to print on the screen what is null
Related
is there any easy way to detect that agent stopped on a roller conveyor because there are other agents ahead? I tried to use dynamic variable and conditional event but it is consuming too much performence. I donĀ“t want to go for dynamically checking condition (with cyclic event) because I have some bad experience with it.
Thanks!
Try this:
Create a LinkedList<YourAgentType> agentsOnConveyor.
Whenever an agent enters the conveyor, call agentsOnConveyor.addLast(agent). When it leaves, call agentsOnConveyor.removeFirst(agent).
Now you have a linked representation of the agents on the conveyor.
Last, you use the "on stopped" field in the conveyor and pass the message "upstream" through the linked list, i.e. use a for-loop from the first to the last entry and send them a msg "conveyor stopped".
You may still need to check if the individual agent is moving itself or has also stopped, but it might put you on a working path
I have 2 storages (called storageA & storageB) and I want to move an agent (pallet) from one to the other via forklifts. I have set up the following.
A pallet is created at a node and is moved to storageA via 'store'. This part works fine. The pallet is then moved to storageB via 'store1' after a delay. This is when the following error occurs:
Exception during discrete event execution:
root.store1.seizeTrans.freeSpaceSendTo:
Path not found! {agent=2, source={level=level, pos=(1673.3333333333333, 3245.0, 0.0)}, target={level=level, pos=(1857.25, 3160.4845, 0.0)}}
It works if I replace 'store1' with a retrieve block and send it to a node first. However I would like to send the pallet directly to another storage rather than via another location. Is this possible?
Please let me know if I have not provided enough information.
Thanks
yeah unfortunately you can't do that as far as I know, the solution I use is the following, which is actually not a super robust solution... but has been ok in applications so far
Place a retrieve block between your delay and your store1
Use the agent you pick up as destination:
on the on seize action of the retrieve block do:agent.transporter=unit;
4.On the store1 block put the highest priority for the task
5. ON the store1 block use resource custom transporter choice: agent.transporter.equals(unit)
6. The dispatching policy should be nearest to the agent in store1, but doing all the above ensures that the resource continues doing the task no matter what... by only using the dispatch policy your model will work 99.999999% of the time... the problem occurs only if another task with higher priority occurs at the exact same time as the transporter is released in the retrieve block, which is rare, but can happen.
I had the same question today so I landed here. But luckily, only after the second step written above, the whole process needed did already work for my case. We can move an agent from one storage to another by simply set the destination of the 'retrieve' block to the coordinate of the agent and the move to independently instead of by fleets or resources. after that we put the 'store' block.
Destination is: (x,y,z)
X: agent.getX()
Y: agent.getY()
Z: agent.getZ()
after agents being retrieved to a specified coordinate, it seems that fleets do not comply paths in the network anymore
I am building a DES-ABM hybrid model in AnyLogic.
The agents go through the DES blocks, among which multiple Delay blocks.
How do I
access an agent which is in a Delay block
or peferrably
acces the specific agent which triggered the 'on enter' action of the delay block?
My ultimate goal is to open or close a valve object on the agent frame
So can I/ how do I
A. open or close the valve on the agent frame directly form the main/root frame (on which the Delay block is located)
or if that is not possible
B. send a message or trigger a statechart within the specific agent which will then open or close the valve from the agent's own frame?
I have tried to use the 'DelayBlockName'.agents() function, but this does not work and returns [] when I check it using traceln.
access an agent which is in a Delay block or peferrably
use the keyword agent. These keywords differ for different library blocks so best start learning about the lightbulb and how it can help, see here.
acces the specific agent which triggered the 'on enter' action of the delay block?
When you write agent. in the "On enter" block, every agent coming through will execute that code, so by definition, it is always the specific agent :)
My ultimate goal is to open or close a valve object on the agent frame So can I/ how do I A. open or close the valve on the agent frame directly form the main/root frame (on which the Delay block is located) or if that is not possible B. send a message or trigger a statechart within the specific agent which will then open or close the valve from the agent's own frame?
this is something completely different to your original question and just... messy. Please limit questions to 1 topic so it is easy for us to answer :) (see this guide for more)
I am trying to run a child job in tLoop. The child job connects to salesforce and downloads "Account" object to local SQL Server table. There are problems with connection to Salesforce, it takes few attempts to connect. Hence, I put the connection stuff in child job and now trying to call the child job in a loop. Below is the image of my parent job.
As you can see in image the tRunJob_1 has error because of Salesforce connection problem in child job. This is correct behaviour.
The setRetryConnect that is connected to OnComponentError has this code: context.retryConnect = true;
The setRetryConnect that is connected to OnComponentOk has this code: context.retryConnect = false;
So, I am tripping this context variable depending on whether child job succeeds or fails.
My tLoop looks as below:
I want the tLoop to run as many times till the condition remains true. That is till the time it continues to error out. However, it just iterates once and then stops. Could anyone please let me know what correction need to be done here to make the tLoop work?
I couldn't re-pro your issue with SalesForce but by looking at your job what I feel is that when you say - "it just iterates once and then stops" is the expected behavior.
As per your job flow after the tRunJob you are using OnComponentOk/OnComponentError trigger which would process and stop the job run as it would have completed the job execution. What it would have ideal was to keep everything in a subjob post tLoop so that it will iterate till the condition is met.
Sample job for explanation -
Here used tSetGlobalVar to define a global variable (in place of your context variable). Then use the globalMap variable as ((Boolean)globalMap.get("tLoop")) in your "Condition" for the tLoop.
And then finally run some code in the tJava component that does something and conditionally sets the global variable to false to mark the ending of loop.
tRunJob provides an Return Code ((Integer)globalMap.get("tRunJob_1_CHILD_RETURN_CODE"))
If you're running your child Job a number of times and want your Job to exit with non-Zero if one of these iterations fails, then after each iteration, you should test this return code and store it in your own globalMap Object if it is non-zero
int returnCode = ((Integer)globalMap.get("tRunJob_1_CHILD_RETURN_CODE"));
if (returnCode > 0) {
globalMap.put("tLoop", false);
}
else {
System.out.println(returnCode);
};
Found the answer myself, posting it here so that it may help others. It appears like OnComponentError breaks the tLoop. Disabled the OnComponentError flow and un-checked the 'Die on Child Error' checkbox in tRunJob.
The tLoop remains as it is. No changes here.
The retryConnect will use the below code. It uses CHILD_RETURN_CODE to check whether the child job threw error. In case of success, its value is 0. I am tripping the variable when the child job succeeds, so the loop will stop. As you can see, the tLoop shows 2 iterations, it is working as expected now. Thanks.
I am trying to use Invoke process to invoke an executable from my windows workflow in my TFS 2010 build.
But when I am looking at the log file it is not logging any error.
I did use WriteBuildMessage and WriteBuildwarning inside my invoke process activity.
I also set the filename,workingdirectory etc in activity.
Can someone please point out why it is not logging?
You can do something like this:
In this case you have to ensure that Message are set as follows:
With those parameters set as depicted, I catch what you seem to be after.
Furthermore, you can check in the Properties of your InvokeProcess: Set the Result into a string-variable and then set in a subsequent WriteBuildMessage this string-variable to be the Message. This way, you 'll additionally catch the return of your invoked process.
EDIT
Another common thing that you 've possibly overlooked is the BuildMessageImportance: if it is not set as High, messages do NOT appear under default Logging Verbosity (= Normal). See here for some background.
In your Invoke Process, you want to set the Result property to update a variable (returns an Int, so lets call it ExitCode), under your Invoke Process (but still in the Agent Scope) you can drop in an If, so you can set the condition of this to ExitCode <> 0 and do whatever you like on a failure (such as failing the build).
Also, as a note, if your WriteBuildMessage is not showing anything in your log, you need to set the Importance to Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High, anything lower and it wont show in the Normal logging level.