Activiti, how to add listener for timer endding? - workflow

img
Hello, I have encounterred a problem about adding a listener to the end event of a timer. I used an intermediate catch event timer to wait a certain period(5 min). After 5 min, the flow goes to task2.
I want to update data in another table(some code in java), so I need a listener that listens the end event of the timer. However, the methods that I tried failed. Would you mind showing me a feasible and easily acomplishable way to do that?
Thanks!

Why not simply add a Task Listener to the complete event of your timer step?
https://www.activiti.org/javadocs/org/activiti/engine/delegate/tasklistener

Related

Event handler for nrf_pwr_mgmt->shutdown_process()

I would like to install an event handler to execute some code before the nRF52 board goes into deep sleep initiated by the NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S. Is there a way to call a function either from the shutdown_process() or sd_power_system_off() without modifying the nrf_pwr_mgmt.c file?

Pause then resuming simulation in Anylogic

I would like to give the user a button that allows them to skip ahead 1 hour in the simulation and then continue running the model if play is clicked. The code below allows the user to skip ahead an hour, however they are unable to resume the simulation when play is clicked.
double nextHour = time() + 60;
pauseSimulation();
getEngine().runFast(nextHour); //Runs the model to the next hour when button is clicked
Any help much appreciated.
Try adding runSimulation() after the last line. But probably, that does not work. In that case:
Create a dynamic event (not the normal event) with the line runSimulation() in its action code.
In the button code, before the runFast... line, write create_MyDynamicEvent(1, HOUR). This will trigger the even 1 hour later and unpause the model.
AnyLogic Support suggested the following solution, which I have used:
Unfortunately, Ben's suggestion didn't didn't work; it seems to cause an issue when pauseSimulation() is used.

Managing multiple events for the same file change generated by pdflatex with a DispatchQueue

I am currently using a DispatchQueue and DispatchSourceFileSystemObject for tracking file changes on a pdf file which is generated by pdflatex. The problem i have is that when pdflatex generate the pdf, it sends several '.write' events and not only one. The job of the handler is to update the corresponding view where the pdf is displayed and i want to avoid to update several times the view with basically the same change(the handler is called every time an event of a specific flag is received). I want to call the handler only once and when the last '.write' event of the same pdf generation occur. For example if the pdflatex produce 10 '.write' events, the handler should be called only when the tenth event has been received.
I have tried to:
check with a flag the current event received to ignore future event with the same flag, and then sleep for some seconds to wait until i receive all the '.write' events but this is not a solution, because depending of the pdf file to generate it could take different time for the process pdflatex to complete.
get the modification date of the file, but with several '.write' sometime the date is the same for every '.write' and sometime it changes for 1 second etc.. so using the Date as a way to call the handler is not a good idea.
I am using a serial queue so the operation are not concurrent in the same queue. I would like, if possible, to continue to use the DisaptchQueue and only if there is no solution i would also appreciate a possible implementation with OperationQueue and Operation or BlockOperation.
I Solved the problem in this way: every time i receive a '.write' event, i try to build a pdfDocument with his url, if the document is nil it means the pdflatex process is still sending '.write' events. In the last '.write' event i can successfully get a pdfDocument because the document has been completed.

Background Process as NSOperation or Thread to monitor and update File

I want to check if a pdf file is changed or not, and if is changed i want to update the corresponding view. I don't know if it's more suitable to use a background process as a Thread or as an NSOperation to do this task. The Apple Documentation says: "Examples of tasks that lend themselves well to NSOperation include network requests, image resizing, text processing, or any other repeatable, structured, long-running task that produces associated state or data.But simply wrapping computation into an object doesn’t do much without a little oversight".
Also, if I understood correctly from the documentation, a Thread once started can't be stopped during his execution while an NSOperation could be paused or stopped and also they could rely on dependency to wait the completion of another task.
The workflow of this task should be more or less this diagram:
Task workflow
I managed to get the handler working after the notification of type .write has been sent. If i monitor for example a *.txt file everything works as expected and i receive only one notification. But i am monitoring a pdf file which is generated from terminal by pdflatex and thus i receive with '.write' nearly 15 notification. If i change to '.attrib' i get 3 notification. I need the handler to be called only once, not 15 or 3 times. Do you have any idea how can i do it or is not possible with a Dispatch Source? Maybe there is a way to execute a dispatchWorkItem only once?
I have tried to implement it like this(This is inside a FileMonitor class):
func startMonitoring()
{
....
let fileSystemRepresentation = fileManager.fileSystemRepresentation(withPath: fileStringURL)
let fileDescriptor = open(fileSystemRepresentation, O_EVTONLY)
let newfileMonitorSource = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor,
eventMask: .attrib,
queue: queue)
newfileMonitorSource.setEventHandler(handler:
{
self.queue.async
{
print(" \n received first write event, removing handler..." )
self.newfileMonitorSource.setEventHandler(handler: nil)
self.test()
}
})
self.fileMonitorSource = newfileMonitorSource
fileMonitorSource!.resume()
}
func test()
{
fileMonitorSource?.cancel()
print(" restart monitoring ")
startMonitoring()
}
I have tried to reassign the handler in test(), but it's not working(if a regenerate the pdf file, what is inside the new handler it's not executed) and to me, doing in this way, it seems a bit boilerplate code. I have also tried the following things:
suspend the DispatchSource in the setEventHandler of startMonitoring() (passing nil), but then when i am resuming it, i get the remaining .write events.
cancel the DispatchSource object and recall the startMonitoring() as you can see in the code above, but in this way i create and destroy the DispatchSource object everytime i receive an event, which i don't like because the cancel() function shoul be called in my case only when the user decide to disable this feauture i am implementing.
I will try to write better how the workflow of the app should be so you can have an more clear idea of what i am doing:
When the app starts, a functions sets the default value of some checkboxes of the window preference. The user can modify this checkboxes. So when the user open a pdf file, the idea is to launch in a background thread the following task:
I create a new queue call it A and launch asynch an infinite while where i check the value of the UserDefault checkboxe (that i use to reload and update the pdf file) and two things could happen
if the user set the value to off and the pdf document has been loaded there could be two situations:
if there is no current monitoring of the file (when the app starts): continue to check the checkboxe value
if there is currently a monitoring of the file: stop it
if the user set value to on and the pdf document has been loaded in this background thread (the same queue A) i will create a class Monitor (that could be a subclass of NSThread or a class that uses DispatchSourceFileSystemObject like above), then i will call startMonitoring() that will check the date or .write events and when there is a change it will call the handler. Basically this handler should recall the main thread (the main queue) and check if the file can be loaded or is corrupted and if so update the view.
Note: The infinite while loop(that should be running in the background), that check the UserDefault related to the feature i am implementing it's launched when the user open the pdf file.
Because of the problem above (multiple handlers calls), i should use the cancel() function when the user set checkboxe to off, and not create/destroy the DispatchSource object everytime i receive a .write event.

How to cancel activity after message boundary event

Having the following process
and a message boundary event which has cancelActivity set to false so that after Should cancel the Sub Process could continue where it was before the event was received - in case that No was selected.
How could I simulate as if cancelActivity was set to true in case that the user selects Yes (i.e. cancel/stop Sub Process when the No end is reached)?
Please ask if I wasn't clear about this.
With the boundary event attached to the sub process, there is no way of going to another task after should cancel.
You can neither use link events (not allowed from parent to sub process), nor a simple sequence flow (not allowed between two processes).
So I guess you need attach the message event to each relevant task within the sub process or you need to use two separate boundary events (one interrupting and one non-interrupting).
Further the answer above.
The process flow really doesnt properly capture your requirement.
You should have the email event running in parallel to your sub process.
On receipt of the email, flow directly into the should cancel human/user task.
If yes, send a signal event (signals are easier to implement than messages) that is captured by a signal boundary event receiver on the sub process and simply flow to the end (i.e. terminate).
If no, you simply exit (you may need to start another email receiver - depends on your requirements).
This way, the sub process boundary event is not triggered until after you have made your decision to terminate or not.
Hope this helps.
maybe you need the bpmn definition below