Skip to main content

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

  • From: Scott Kurz < >
  • To:
  • Subject: [jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?
  • Date: Sat, 16 Mar 2013 00:42:51 -0400

Cheng,

Thanks for forcing a rethink of the issue...  I think we can indeed make that change, and I agree it's a better approach.

Even in the RI, it appears awkward to have function interlaced, centered around meeting the needs of the TCK.   I'd just thought if no one cared, we'd leave it, but
yes, I like this better.

I'll paste a prototype that does polling and could live in the TCK itself, and not the RI...  (sorry not ready for Git checkin)...

It has the virtue of allowing our existing TCK "util" API (JobOperatorBridge.startJobAndWaitForResult(), etc.) to function unchanged.....  

We just wouldn't have time to do something that would require line by line inspection of the TCK test driver methods, but this actually works out nicely...

Thanks again...

Code pasted here (figure you don't want an email attachment):

------------------------------------------------------------------------------
// New interfaces in  package com.ibm.jbatch.tck.spi;

public interface BatchContainerServiceProvider {
    public JobExecutionWaiterFactory getWaiterFactory();
}

public interface JobExecutionWaiter {
JobExecution awaitTermination() throws TimeoutException;
}

public interface JobExecutionWaiterFactory {
public JobExecutionWaiter createWaiter(long executionId, JobOperator jobOp, long sleepTime);
}


------

// Prototype impl

/*
 * Copyright 2013 International Business Machines Corp.
 *
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership. Licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ibm.jbatch.tck.polling;

import javax.batch.operations.JobOperator;
import javax.batch.operations.JobOperator.BatchStatus;
import javax.batch.operations.JobSecurityException;
import javax.batch.operations.NoSuchJobExecutionException;
import javax.batch.runtime.JobExecution;
import java.lang.IllegalStateException;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;

import com.ibm.jbatch.tck.spi.JobExecutionWaiter;
import com.ibm.jbatch.tck.spi.JobExecutionWaiterFactory;
import com.ibm.jbatch.tck.spi.TimeoutException;

public class TCKPollingExecutionWaiterFactory implements JobExecutionWaiterFactory {

    private final static String sourceClass = TCKPollingExecutionWaiterFactory.class.getName();
    private final static Logger logger = Logger.getLogger(sourceClass);
   
private final int POLL_INTERVAL = 100; // .1 second

@Override
public JobExecutionWaiter createWaiter(long executionId, JobOperator jobOp, long sleepTime) {
return new TCKPollingExecutionWaiter(executionId, jobOp, sleepTime);
}

private class TCKPollingExecutionWaiter implements JobExecutionWaiter {

private long executionId;
private JobOperator jobOp;
private long sleepTime;

private TCKPollingExecutionWaiter(long executionId, JobOperator jobOp, long sleepTime) {
logger.fine("Creating waiter for executionId = " + executionId + ", jobOp = " + jobOp + ", sleepTime = " + sleepTime);
this.executionId = executionId;
this.jobOp = jobOp;
this.sleepTime = sleepTime;
}

@Override
public JobExecution awaitTermination() throws TimeoutException {
logger.fine("Entering awaitTermination for executionId = " + executionId);
JobExecution jobExecution = null;
while (true) {
try {
logger.finer("Sleeping for " + POLL_INTERVAL);
Thread.sleep(POLL_INTERVAL);
logger.finer("Wake up, check for termination.");
jobExecution = jobOp.getJobExecution(executionId);
if (isTerminatedStatus(jobExecution)) {
logger.fine("Found terminating batch status of: " + jobExecution.getBatchStatus().name());
break;
} else {
logger.finer("Found non-terminating batch status of: " + jobExecution.getBatchStatus().name());
}
} catch (InterruptedException e) {
throw new IllegalStateException("Aborting on interrupt", e);
} catch (JobSecurityException e) {
throw new IllegalStateException("Aborting on security (authorization) exception", e);
} catch (NoSuchJobExecutionException e) {
throw new IllegalStateException("JobExecution disappeared for exec id =" + executionId);
}
}
return jobExecution;
}

private boolean isTerminatedStatus(JobExecution jobExecution) {
BatchStatus bs = jobExecution.getBatchStatus();
return terminatedStatuses.contains(bs);
}


}
// Full list:
//public enum BatchStatus {STARTING, STARTED, STOPPING, STOPPED, FAILED, COMPLETED, ABANDONED }
private static Set<BatchStatus> terminatedStatuses = new HashSet<BatchStatus>();
static {
terminatedStatuses.add(BatchStatus.STOPPED);
terminatedStatuses.add(BatchStatus.FAILED);
terminatedStatuses.add(BatchStatus.COMPLETED);
terminatedStatuses.add(BatchStatus.ABANDONED);
}

}
------------------------------------------------------
Scott Kurz
WebSphere Batch / Compute Grid Development
T/L 295-5649;
External Phone 845-435-5649

--------------------------------------------------------


Inactive hide details for Cheng Fang ---03/15/2013 10:23:30 PM---The current spi seems to assume some kind of job end callback Cheng Fang ---03/15/2013 10:23:30 PM---The current spi seems to assume some kind of job end callback is  implemented by a batch runtime.  B

From: Cheng Fang < >
To: ,
Date: 03/15/2013 10:23 PM
Subject: [jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?





The current spi seems to assume some kind of job end callback is implemented by a batch runtime.  But since it's not required by the spec, it may be too much for a batch runtime to provide it just for running the tck.  

Coming back to the polling, to maintain a list of executions also puts extra demand on a batch implementation.

Let's forget about the job end callback for a moment.  What the test driver needs is waiting for the test job to terminate before checking result (I may be greatly simplifying or missing a few things here).  Job end callback is one way of achieving that, and seems well supported by how RI is implemented.  As part of this contract between test driver and batch runtime, I think the current StepExecution (and preferably JobOperator) needs to be passed along, to accommodate different batch runtime implementation strategies.

So I'm hoping for a more generic tck spi, along the line of:

JobExecutionWaiter.awaitTermination(StepExecution, JobOperator, long timeout);

JobExecutionWaiterImpl is then provided by tck user with whatever mechanism suitable for the target runtime.  If a job is already done, it returns immediately; otherwise, it blocks till the job terminates, or timeout.

Cheng

On 3/15/13 2:45 PM, Scott Kurz wrote:

    Cheng,

    So the polling approach would be a bit coarse-grained...without knowing the execution id upfront, you'd have to do something like:


     - build an initial list of all JobExecution(s) already in a final state
     - on each iteration of poll(), note the newly-finalized executions, and fire the notification for each registered callback.


    I do think it's too late to add this to the spec as an API.....


    But the approach above probably doesn't fit well as a "TCK utility" as I'd suggested, and maybe should be implementation-specific.

    ------------------------------------------------------
    Scott Kurz
    WebSphere Batch / Compute Grid Development
    T/L 295-5649;
    External Phone 845-435-5649

    ">
    --------------------------------------------------------


    Inactive
          hide details for Scott Kurz---03/15/2013 01:08:42 AM---Cheng,
          Since the TCK SPI is a contract any implementor must meeScott Kurz---03/15/2013 01:08:42 AM---Cheng, Since the TCK SPI is a contract any implementor must meet to run the TCK, we definitely want

    From:
    Scott Kurz/Poughkeepsie/IBM
    To:
    "> ,
    Date:
    03/15/2013 01:08 AM
    Subject:
    Re: [jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?




    Cheng,


    Since the TCK SPI is a contract any implementor must meet to run the TCK, we definitely want to get it right and try to address your concerns.


    Yes, it seems like you'd need at least the executionId to do the polling I'd suggested.  


    The JobOperator seems useful too and on quick review, I can't see a downside in requiring it be obtainable.  


    Thanks for giving this some more  thought.   Do you think then that those two methods would be sufficient?


    ------------------------------------------------------
    Scott Kurz
    WebSphere Batch / Compute Grid Development
    T/L 295-5649;
    External Phone 845-435-5649

    ">
    --------------------------------------------------------



    Inactive
        hide details for Cheng Fang ---03/14/2013 11:00:26 PM---Thanks
        Scott for your thoughts and consideration. If we have Cheng Fang ---03/14/2013 11:00:26 PM---Thanks Scott for your thoughts and consideration.  If we have to defer  it to JSR 352.next due to ti

    From:
    Cheng Fang ">< >
    To:
    "> ,
    Date:
    03/14/2013 11:00 PM
    Subject:
    [jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?




    Thanks Scott for your thoughts and consideration.  If we have to defer it to JSR 352.next due to time constraint, that's fine with me.

    w.r.t. the TCK SPI, is it fully functional with a 3rd party implementation?  The tck guide says 3 interfaces need to be implemented, but in the test class JobOperatorBridge, JobEndCallbackImpl is used directly.  So looks like the tck user doens't need to implement this interface, and it has no role in how the tck spi impl connects to batch runtime.

    However, JobEndCallback doesn't provide enough information and operations, with only 1 method done(long l).  It is not sufficient to allow for various types of tck spi implementation, including the polling strategy you suggested.  Can we add more to JobEndCallback, such as:

    getJobExecution();
    getJobOperator();

    gJobOperator can be loaded by tck spi impl, but it would be easier if it is available from the callback object.

    Cheng

    On 3/13/13 11:23 PM, Scott Kurz wrote:

      Cheng,

      Thanks for considering this SPI and for your proposal.

      With our heads down in the TCK I'd been hoping others would raise the question of whether this was more generally useful or
      if it were just a TCK-centric concern.      

      It is an onerous part of running the TCK against one's implementation that seems to call for a common solution.

      Let me run by you a related thought I had here... this last issue, (your benefit #1), could be gained by simply implementing

      JobEndCallbackManager
      with a piece of code that does polling.   Further, this doesn't seem to me to be needed to complete
      in the JSR timeframe... it could even be done later by someone running the TCK against something besides the RI (an important factor
      since we're having this conversation with less than two weeks before our code freeze.

      I realize you're arguing for it being part of the spec API.. just saying we don't need to add that just for the TCK.   That wouldn't be off the
      table completely in my mind, even given the time, since so many pieces are already in place.    

      The only caveat... like we did to the TCK with the loss of JobExecution's getInstanceId().. we might wrap our way out of it so as to make the change as quickly
      as possible... even if that leaves the test methods themselves looking a bit atypical compared to "normal" API usage.

      Scott Kurz
       

GIF image



[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

(continued)

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

03/14/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Scott Kurz 03/14/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Christopher Vignola 03/14/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Michael Minella 03/14/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Scott Kurz 03/14/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Cheng Fang 03/15/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Scott Kurz 03/15/2013

Message not available

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Scott Kurz 03/15/2013

Message not available

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Scott Kurz 03/15/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Cheng Fang 03/16/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Scott Kurz 03/16/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Michael Minella 03/16/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Scott Kurz 03/16/2013

[jsr352-public] Re: JobExecution.awaitCompletion(long timeout)?

Cheng Fang 03/17/2013
 
 
Close
loading
Please Confirm
Close