-
Notifications
You must be signed in to change notification settings - Fork 365
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added retries to service level methods that make persistence calls. (#…
…413) * Added retries to service level methods that make persistence calls. * Review changes. * Review changes. * Review changes. * Review changes. * Review changes.
- Loading branch information
1 parent
dedbaaa
commit 8b0e6df
Showing
12 changed files
with
448 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
genie-core/src/main/java/com/netflix/genie/core/properties/DataServiceRetryProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
* | ||
* Copyright 2016 Netflix, Inc. | ||
* | ||
* 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.netflix.genie.core.properties; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
/** | ||
* All properties related to data service retry template in Genie. | ||
* | ||
* @author amajumdar | ||
* @since 3.0.0 | ||
*/ | ||
@Getter | ||
@Setter | ||
public class DataServiceRetryProperties { | ||
/** | ||
* Default to 5 retries. | ||
*/ | ||
private int noOfRetries = 5; | ||
|
||
/** | ||
* Default to 100 ms. | ||
*/ | ||
private long initialInterval = 100L; | ||
|
||
/** | ||
* Defaults to 30000 ms. | ||
*/ | ||
private long maxInterval = 30000L; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
genie-web/src/main/java/com/netflix/genie/web/aspect/DataServiceRetryAspect.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* | ||
* | ||
* Copyright 2016 Netflix, Inc. | ||
* | ||
* 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.netflix.genie.web.aspect; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import com.netflix.genie.common.exceptions.GenieException; | ||
import com.netflix.genie.common.exceptions.GenieServerException; | ||
import com.netflix.genie.core.properties.DataServiceRetryProperties; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.aspectj.lang.ProceedingJoinPoint; | ||
import org.aspectj.lang.annotation.Around; | ||
import org.aspectj.lang.annotation.Aspect; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.core.Ordered; | ||
import org.springframework.dao.CannotAcquireLockException; | ||
import org.springframework.dao.ConcurrencyFailureException; | ||
import org.springframework.dao.DeadlockLoserDataAccessException; | ||
import org.springframework.dao.OptimisticLockingFailureException; | ||
import org.springframework.dao.PessimisticLockingFailureException; | ||
import org.springframework.dao.QueryTimeoutException; | ||
import org.springframework.dao.TransientDataAccessResourceException; | ||
import org.springframework.jdbc.CannotGetJdbcConnectionException; | ||
import org.springframework.orm.jpa.JpaSystemException; | ||
import org.springframework.retry.RetryListener; | ||
import org.springframework.retry.backoff.ExponentialBackOffPolicy; | ||
import org.springframework.retry.policy.SimpleRetryPolicy; | ||
import org.springframework.retry.support.RetryTemplate; | ||
import org.springframework.stereotype.Component; | ||
|
||
import javax.validation.ConstraintViolationException; | ||
|
||
/** | ||
* Aspect implementation of retrying the data service methods on certain failures. | ||
* @author amajumdar | ||
* @since 3.0.0 | ||
*/ | ||
@Aspect | ||
@Component | ||
@Slf4j | ||
public class DataServiceRetryAspect implements Ordered { | ||
private final RetryTemplate retryTemplate; | ||
|
||
/** | ||
* Constructor. | ||
* @param dataServiceRetryProperties retry properties | ||
*/ | ||
@Autowired | ||
public DataServiceRetryAspect(final DataServiceRetryProperties dataServiceRetryProperties) { | ||
retryTemplate = new RetryTemplate(); | ||
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(dataServiceRetryProperties.getNoOfRetries(), | ||
new ImmutableMap.Builder<Class<? extends Throwable>, Boolean>() | ||
.put(CannotGetJdbcConnectionException.class, true) | ||
.put(CannotAcquireLockException.class, true) | ||
.put(DeadlockLoserDataAccessException.class, true) | ||
.put(OptimisticLockingFailureException.class, true) | ||
.put(PessimisticLockingFailureException.class, true) | ||
.put(ConcurrencyFailureException.class, true) | ||
// Will this work for cases where the write queries timeout on the client? | ||
.put(QueryTimeoutException.class, true) | ||
.put(TransientDataAccessResourceException.class, true) | ||
.put(JpaSystemException.class, true) | ||
.build())); | ||
final ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy(); | ||
backOffPolicy.setInitialInterval(dataServiceRetryProperties.getInitialInterval()); | ||
backOffPolicy.setMaxInterval(dataServiceRetryProperties.getMaxInterval()); | ||
retryTemplate.setBackOffPolicy(backOffPolicy); | ||
} | ||
|
||
/** | ||
* Sets the retry listeners for the retry template in use. | ||
* @param retryListeners retry listeners | ||
*/ | ||
public void setRetryListeners(final RetryListener[] retryListeners) { | ||
retryTemplate.setListeners(retryListeners); | ||
} | ||
|
||
/** | ||
* Aspect implementation method of retrying the data service method on certain failures. | ||
* @param pjp join point | ||
* @return return the data method response | ||
* @throws GenieException any exception thrown by the data service method | ||
*/ | ||
@Around("com.netflix.genie.web.aspect.SystemArchitecture.dataOperation()") | ||
public Object profile(final ProceedingJoinPoint pjp) throws GenieException { | ||
try { | ||
return retryTemplate.execute(context -> pjp.proceed()); | ||
} catch (GenieException | ConstraintViolationException e) { | ||
throw e; | ||
} catch (Throwable e) { | ||
throw new GenieServerException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public int getOrder() { | ||
// Currently setting this to 0 since we want the retry to happen before the transaction interceptor. | ||
return 0; | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
genie-web/src/main/java/com/netflix/genie/web/aspect/SystemArchitecture.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* | ||
* Copyright 2016 Netflix, Inc. | ||
* | ||
* 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.netflix.genie.web.aspect; | ||
|
||
import org.aspectj.lang.annotation.Aspect; | ||
import org.aspectj.lang.annotation.Pointcut; | ||
import org.springframework.stereotype.Component; | ||
|
||
/** | ||
* Application pointcut expressions. | ||
* @author amajumdar | ||
* @since 3.0.0 | ||
*/ | ||
@Aspect | ||
@Component | ||
public class SystemArchitecture { | ||
/** | ||
* A join point is in the resource layer if the method is defined | ||
* in a type in the com.netflix.genie.web.controllers package or any sub-package | ||
* under that. | ||
*/ | ||
@Pointcut("within(com.netflix.genie.web.controllers..*)") | ||
public void inResourceLayer() { } | ||
|
||
/** | ||
* A join point is in the service layer if the method is defined | ||
* in a type in the com.netflix.genie.core.services package or any sub-package | ||
* under that. | ||
*/ | ||
@Pointcut("within(com.netflix.genie.core.services..*)") | ||
public void inServiceLayer() { } | ||
|
||
/** | ||
* A join point is in the data service layer if the method is defined | ||
* in a type in the com.netflix.genie.core.jpa.services package or any sub-package | ||
* under that. | ||
*/ | ||
@Pointcut("within(com.netflix.genie.core.jpa.services..*)") | ||
public void inDataLayer() { } | ||
|
||
/** | ||
* A resource service is the execution of any method defined on a controller. | ||
* This definition assumes that interfaces are placed in the | ||
* "resources" package, and that implementation types are in sub-packages. | ||
*/ | ||
@Pointcut("execution(* com.netflix.genie.web.controllers.*.*(..))") | ||
public void resourceOperation() { } | ||
|
||
/** | ||
* A service operation is the execution of any method defined on a | ||
* service class/interface. This definition assumes that interfaces are placed in the | ||
* "service" package, and that implementation types are in sub-packages. | ||
*/ | ||
@Pointcut("execution(* com.netflix.genie.core.services.*.*(..))") | ||
public void serviceOperation() { } | ||
|
||
/** | ||
* A data service operation is the execution of any method defined on a | ||
* dao interface. This definition assumes that interfaces are placed in the | ||
* "dao" package, and that implementation types are in sub-packages. | ||
*/ | ||
@Pointcut("execution(* com.netflix.genie.core.jpa.services.*.*(..))") | ||
public void dataOperation() { } | ||
} |
25 changes: 25 additions & 0 deletions
25
genie-web/src/main/java/com/netflix/genie/web/aspect/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* | ||
* Copyright 2016 Netflix, Inc. | ||
* | ||
* 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. | ||
* | ||
*/ | ||
|
||
/** | ||
* Various Spring aspects for Genie web. | ||
* | ||
* @author amajumdar | ||
* @since 3.0.0 | ||
*/ | ||
package com.netflix.genie.web.aspect; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.