001/* 002 * Copyright 2006-2007 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.batch.repeat.policy; 018 019import org.springframework.batch.repeat.RepeatContext; 020import org.springframework.batch.repeat.context.RepeatContextSupport; 021 022/** 023 * Termination policy that times out after a fixed period. Allows graceful exit 024 * from a batch if the latest result comes in after the timeout expires (i.e. 025 * does not throw a timeout exception).<br> 026 * 027 * N.B. It may often be the case that the batch governed by this policy will be 028 * transactional, and the transaction might have its own timeout. In this case 029 * the transaction might throw a timeout exception on commit if its timeout 030 * threshold is lower than the termination policy. 031 * 032 * @author Dave Syer 033 * 034 */ 035public class TimeoutTerminationPolicy extends CompletionPolicySupport { 036 037 /** 038 * Default timeout value in milliseconds (the value equivalent to 30 seconds). 039 */ 040 public static final long DEFAULT_TIMEOUT = 30000L; 041 042 private long timeout = DEFAULT_TIMEOUT; 043 044 /** 045 * Default constructor. 046 */ 047 public TimeoutTerminationPolicy() { 048 super(); 049 } 050 051 /** 052 * Construct a {@link TimeoutTerminationPolicy} with the specified timeout 053 * value (in milliseconds). 054 * 055 * @param timeout duration of the timeout. 056 */ 057 public TimeoutTerminationPolicy(long timeout) { 058 super(); 059 this.timeout = timeout; 060 } 061 062 /** 063 * Check the timeout and complete gracefully if it has expires. 064 * 065 * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(org.springframework.batch.repeat.RepeatContext) 066 */ 067 @Override 068 public boolean isComplete(RepeatContext context) { 069 return ((TimeoutBatchContext) context).isComplete(); 070 } 071 072 /** 073 * Start the clock on the timeout. 074 * 075 * @see org.springframework.batch.repeat.CompletionPolicy#start(RepeatContext) 076 */ 077 @Override 078 public RepeatContext start(RepeatContext context) { 079 return new TimeoutBatchContext(context); 080 } 081 082 protected class TimeoutBatchContext extends RepeatContextSupport { 083 084 private volatile long time = System.currentTimeMillis(); 085 086 private final long timeout = TimeoutTerminationPolicy.this.timeout; 087 088 public TimeoutBatchContext(RepeatContext context) { 089 super(context); 090 } 091 092 public boolean isComplete() { 093 return (System.currentTimeMillis() - time) > timeout; 094 } 095 096 } 097 098}