Not able to end the workflow when thread stops

170 Views Asked by At

I am just not able to figure out the cause of this issue.

Problem :

1) I am using a Thread.Sleep function to set the timer for my application.

2) Now as soon as user enter the webPage the timer starts, if user clicks any link the timer(thread) is stopped and then new timer starts.

3) If their is no activity for say 3 seconds, timer ends and with it workflow associated with the webpage ends too.

Code :

DownloadSummariesPage.java

public DownloadSummariesPage(){

 abc = new SimpleThread(this);

Link<Void> link = new Link<Void>("downloadSummaryLink") {

public void onClick() {

                    boolean threadStatus = abc.checkStatus();

                    if (threadStatus) {
                        abc.interrupt();
                        abc.stop();
                        abc = new SimpleThread(DownloadSummariesPage.this);
                        abc.start();
                        } 
                    else 
                        {
                        LOG.debug("thread is dead now");
                        endWorkflow();
                        LOG.debug("ending the workflow");
                        setResponsePage(MenuPage.class);                        
                        }
                     }

};
abc.start();
}


public void endWorkflow() {
    abc.interrupt();
    abc.stop();
    boolean downloadReport = false;
    LOG.debug("before action 201 inside endworkflow");
    Map<String, Serializable> inputs = new HashMap<String, Serializable>();
    inputs.put("downloadReport", downloadReport);
    try {
        wf.doAction(id, 201, inputs);//do not worry about this its for workflow
        String empty = "";
        populateDownloadReportDatabase(empty);

        setResponsePage(MenuPage.class);
    } catch (Exception e) {
        LOG.debug("Exception while performing 201 workflow, getControlCancel "
                + e);
    }
}
}

My next class which creates thread is SimpleThread.java

class SimpleThread extends Thread {
private static final Logger LOG = Logger.getLogger(SimpleThread.class);

boolean stillActive = true;
DownloadSummariesPage dsp;

SimpleThread(DownloadSummariesPage dp) {
    this.dsp = dp;
}

public void run() {
    // 5sec timer
    LOG.debug("inside run method");
    try {
        Thread.sleep(3000);
        stillActive = false;
    } catch (InterruptedException e) {
        LOG.debug("Exception in thread " + e);
        e.printStackTrace();
    }
    LOG.debug("before endworkflow");
    dsp.endWorkflow();//so this is what i actually want to do...
    LOG.debug("at the end of simplethread");

}

public boolean checkStatus() {
    return stillActive;
}
}

Cases :

1) Whats Happening : User logs in thread sleeps, user click a link thread stops and creates a new one if user again click it happens again and now if user do not do anything for 3 seconds, stillAlive variable in SimpleThread class is set to false and when now user click its ends the workflow perfectly...

2) What i want : if user logs in thread starts, and if their is no activity by the user stillAlive variable is set to false and dsp.endWorkflow(); statement now should end the workflow. right ? but it just stops after reaching inside the endWorkflow() function and do not actually end the workflow...

Hope you get this, I tried my best to make it understandable. Thanks for your time..

I appreciate any help..

1

There are 1 best solutions below

2
On

So there are some strange things here.
first assume the thread sleep without any interruption for 3 sec, so it will call the dsp.endWorkflow() where you call it again from the onClick method.

second the stillAlive flag should be volatile

boolean volatile stillActive = true;

The possible error/bug would raises by this section.

if (threadStatus) {
abc.interrupt();
abc.stop();// you cannot get to this like just after interrupt, maybe thread abc goes first
abc = new SimpleThread(DownloadSummariesPage.this);
abc.start();
} 

because assume when thread is sleeping you interrupt it, then stop it, but this is possible that thread finishes it's work just after you interrupt it (before you stop it). so this is better to just stop it, or return when thread reached the catch.

    try {
        Thread.sleep(3000);
        stillActive = false;
    } catch (InterruptedException e) {
        LOG.debug("Exception in thread " + e);
        e.printStackTrace();
        return;//////give up the rest work. so you don't need to call the stop too.
    }

And the error is here assume that user don't click the cancel, or new download, and thread just finishes its sleeping and call the dsp.endWorkflow(), so what is going on this method?

public void endWorkflow() {
    abc.interrupt();
    abc.stop();//error here!
    boolean downloadReport = false;//this is unreachable
}

Just look, you are calling this method by abc thread, and the error is that you are killing the thread just inside the method, before you set the downloadReport to false. so it may would be like this.

public void endWorkflow() {
    boolean downloadReport = false;//this is unreachable
    abc.interrupt();
    abc.stop();//error here!
}

I hope I could some help.