How to get notified when the process invoked using Apache Commons Exec has stopped? - apache

I am invoking a java process using Apache exec library. I need to do some operation if the process is forcefully stopped ( using task manager or some other way). Is there any option available in exec library ? I found a waitfor() operation in ResultHandler, which is doing a busy wait. Is there any notification mechanism available ?

I would expect the exit status to reflect if the process had been forceably killed.
See the tutorial and in particular reference to your comment, this section:
Your worker thread will block until the print process has finished or
was killed by the watchdog. Therefore executing the print job
asynchronously will do the trick. In this example we create an
instance of 'ExecuteResultHandler' and pass it to the 'Executor'
instance in order to execute the process asynchronously. The
'resultHandler' picks up any offending exception or the process exit
code

This has been asked a long time ago but I stumbled upon it today...
Here is the solution: you just have to setup a ExecuteResultHandler and pass it to the execute method. Then no active wait involved. Like this:
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler() {
#Override
public void onProcessComplete(int exitValue) {
super.onProcessComplete(exitValue);
log.info("Process finished");
}
#Override
public void onProcessFailed(ExecuteException e) {
super.onProcessFailed(e);
log.info("Process failed miserably");
}
};
String process = "C:\\Program Files (x86)\\Adobe\\Acrobat Reader DC\\Reader\\AcroRd32.exe";
CommandLine cmdLine = new CommandLine(process);
cmdLine.addArgument("C:\\Users\\francois.marot\\Downloads\\UtiliserLesDernieres DLL.pdf");
DefaultExecutor executor = new DefaultExecutor();
// the watchdog purpose is to kill the process after a specified timeout
SphereExecutionWatchdog watchdog = new SphereExecutionWatchdog(5000);
executor.setWatchdog(watchdog);
executor.execute(cmdLine, resultHandler);

Related

How to make batch processing with Apex?

How can I create batch processing application with Apache Apex?
All the examples I've found were streaming applications, which means they are not ending and I would like my app to close once it has processed all the data.
Thanks
What is your use-case? Supporting batch natively is on the roadmap and is being worked on right now.
Alternately, till then, once you are sure that your processing is done, the input operator can send a signal as ShutdownException() and that will propogate through the DAG and shutdown the DAG.
Let us know if you need further details.
You can add an exit condition before running the app.
for example
public void testMapOperator() throws Exception
{
LocalMode lma = LocalMode.newInstance();
DAG dag = lma.getDAG();
NumberGenerator numGen = dag.addOperator("numGen", new NumberGenerator());
FunctionOperator.MapFunctionOperator<Integer, Integer> mapper
= dag.addOperator("mapper", new FunctionOperator.MapFunctionOperator<Integer, Integer>(new Square()));
ResultCollector collector = dag.addOperator("collector", new ResultCollector());
dag.addStream("raw numbers", numGen.output, mapper.input);
dag.addStream("mapped results", mapper.output, collector.input);
// Create local cluster
LocalMode.Controller lc = lma.getController();
lc.setHeartbeatMonitoringEnabled(false);
//Condition to exit the application
((StramLocalCluster)lc).setExitCondition(new Callable<Boolean>()
{
#Override
public Boolean call() throws Exception
{
return TupleCount == NumTuples;
}
});
lc.run();
Assert.assertEquals(sum, 285);
}
for the complete code refer https://github.com/apache/apex-malhar/blob/master/stream/src/test/java/org/apache/apex/malhar/stream/FunctionOperator/FunctionOperatorTest.java

Injecting Variables into a running Process

Is there a way to inject a variable into a running process without a process listening for RPC requests?
For example if a process was running and using an environment variable, could I change that environment variable at runtime and make the process use the new value?
Are there alternative solutions for dynamically changing variables in a running process? Assume that this process is like a PHP process or a Javascript (node.js) process so I can change the source code... etc.
I think this is similar to passing state or communicating to another process, but I need a really lightweight way of doing so, without going over the network or using libraries or preferably not setting up an RPC server.
Solution does not have to be cross-platform. Prefer Linux.
You can do it it java. Imagine this is your thread class:
public void ThreadClass extends Thread {
Boolean state;
ThreadClass(Boolean b) {
state = b;
}
public void StopThread() {
state = false;
}
public void run() {
while(state) { //Do whatever you want here}
}
}
Now all you have to do is start this thread from your main class:
ThreadClass thread = new ThreadClass(true);
thread.start();
And if you want to change the value of state, call the StopThread method in the thread like so:
try {
thread.StopThread();
} catch (InterruptedException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
This will change the state of the Boolean while the thread is running.
It appears that local IPC implementations like shared memory is the way to go: Fastest technique to pass messages between processes on Linux?

Asynchronously start only one Task to process a static Queue, stopping when it's done

Basically I have a static custom queue of objects I want to process. From multiple threads, I need to kick off a singular Task that will process the queued objects, stopping the task when all items are dequeued.
Some psuedo code:
static CustomQueue _customqueue;
static Task _processQueuedItems;
public static void EnqueueSomething(object something) {
_customqueue.Enqueue(something);
StartProcessingQueue();
}
static void StartProcessingQueue() {
if(_processQueuedItems != null) {
_processQueuedItems = new Task(() => {
while(_customqueue.Any()) {
var stuffToDequeue = _customqueue.Dequeue();
/* do stuff */
}
});
_processQueuedItems.Start();
}
if(_processQueuedItems.Status != TaskStatus.Running) {
_processQueuedItems.Start();
}
}
If it makes a difference my custom queue is a queue that essentially holds items until they reach a certain age, then allows them to dequeue. Everytime an item is touched its timer starts again. I know this piece works fine.
The part I'm struggling with is the parallelism. (Clearly, I don't know what I'm doing here). What I want is to have one thread process the queue until it's complete, then go away. If another call comes in it doesn't start a new thread unless it has to.
I hope that explains my issue okay.
You might want to consider using BlockingCollection<T> here. You could make your custom queue implement IProducerConsumerCollection, in which case BC could use it directly.
You'd then just need to start a long running Task to call blockingCollection.GetConsumingEnumerable() and process the items in a foreach. The task will automatically block when the collection is empty, and restart when a new item is Enqueued.

Memory leak using WCF GetCallbackChannel over named pipe

We have a simple wpf application that connects to a service running on the local machine. We use a named pipe for the connection and then register a callback so that later the service can send updates to the client.
The problem is that with each call of the callback we get a build up of memory in the client application.
This is how the client connects to the service.
const string url = "net.pipe://localhost/radal";
_channelFactory = new DuplexChannelFactory<IRadalService>(this, new NetNamedPipeBinding(),url);
and then in a threadpool thread we loop doing the following until we are connected
var service = _channelFactory.CreateChannel();
service.Register();
service.Register looks like this on the server side
public void Register()
{
_callback = OperationContext.Current.GetCallbackChannel<IRadalCallback>();
OperationContext.Current.Channel.Faulted += (sender, args) => Dispose();
OperationContext.Current.Channel.Closed += (sender, args) => Dispose();
}
This callback is stored and when new data arrives we invoke the following on the server side.
void Sensors_OnSensorReading(object sender, SensorReadingEventArgs e)
{
_callback.OnReadingReceived(e.SensorId, e.Count);
}
Where the parameters are an int and a double. On the client this is handled as follows.
public void OnReadingReceived(int sensorId, double count)
{
_events.Publish(new SensorReadingEvent(sensorId, count));
}
But we have found that commenting out _event.Publish... makes no difference to the memory usage. Does anyone see any logical reason why this might be leaking memory. We have used a profiler to track the problem to this point but cannot find what type of object is building up.
Well I can partially answer this now. The problem is partially caused by us trying to be clever and getting the connection to be opened on another thread and then passing it back to the main gui thread. The solution was to not use a thread but instead use a dispatch timer. It does have the downside that the initial data load is now on the GUI thread but we are not loading all that much anyway.
However this was not the entire solution (actually we don't have an entire solution). Once we moved over to a better profiler we found out that the objects building up were timeout handlers so we disabled that feature. That's OK for us as we are running against the localhost always but I can imagine for people working with remote services it would be an issue.

How do I wait till a db query is completed?

Currently I'm executing db queries this way:
_svc = new Service1Client();
_svc.GetStateCompleted += new EventHandler<GetStateCompletedEventArgs>(_svc_GetStateCompleted);
private void _svc_GetStateCompleted(object sender, userdetCompletedEventArgs e)
{
//some code
}
Calling the query function,
_svc.GetStateAsync(args);
//more code
Is there anyway I can wait after GetStateAsync till the service function returns a value?
Typically you do not wait for a long running operation to complete. There are ways to achieve that, but normally if you do not want users to interact with the application until it completes - you disable all inputs and show some sort of a progress indicator until the operation completes.