Skip to content
Permalink
Browse files
GERONIMO-6598 - Ability to customize the executor service. Document s…
…ome of the integration needs.
  • Loading branch information
johnament committed Feb 17, 2018
1 parent a4f9c30 commit 536d61e902e15518a4c6a678307a19a47be1d278
Showing 6 changed files with 123 additions and 9 deletions.
@@ -49,3 +49,31 @@ Apache Safeguard is currently in development; however a 1.0 release was created
```

Apache Safeguard implements the [MicroProfile Fault Tolerance v1.0 specification](https://github.com/eclipse/microprofile-fault-tolerance/releases/tag/1.0)

### Integration

The core of Safeguard is wrapped around an `ExecutionManager` which takes care of coordinating and storing the execution state of various methods. It allows some configurability, but if you want to change it your best solution is to create an alternative of `ExecutionManager` with your customizations. For instance, in an EE environment you may want to use a `ManagedScheduledExecutorService` which could be done:

```java
@ApplicationScoped
@Specializes
@Priority(100)
public class MyExecutionManagerProvider extends FailsafeExecutionManagerProvider{
@Resource
private ManagedScheduledExecutorService executorService;
@Produces
@ApplicationScoped
public ExecutionManager createExecutionManager() {
FailsafeCircuitBreakerManager circuitBreakerManager = new FailsafeCircuitBreakerManager();
FailsafeRetryManager retryManager = new FailsafeRetryManager();
BulkheadManagerImpl bulkheadManager = new BulkheadManagerImpl();
DefaultExecutorServiceProvider executorServiceProvider = new DefaultExecutorServiceProvider(executorService);
ExecutionPlanFactory executionPlanFactory = new ExecutionPlanFactory(circuitBreakerManager, retryManager, bulkheadManager, mapper,
executorServiceProvider);
return FailsafeExecutionManager(MicroprofileAnnotationMapper.getInstance(), bulkheadManager, circuitBreakerManager,
retryManager, executionPlanFactory, executorServiceProvider);
}
}
```
@@ -27,13 +27,16 @@
import org.apache.safeguard.impl.circuitbreaker.FailsafeCircuitBreakerManager;
import org.apache.safeguard.impl.config.MicroprofileAnnotationMapper;
import org.apache.safeguard.impl.executionPlans.ExecutionPlanFactory;
import org.apache.safeguard.impl.executorService.DefaultExecutorServiceProvider;
import org.apache.safeguard.impl.executorService.ExecutorServiceProvider;
import org.apache.safeguard.impl.retry.FailsafeRetryManager;

import javax.enterprise.inject.Vetoed;
import javax.interceptor.InvocationContext;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

@Vetoed
public class FailsafeExecutionManager implements ExecutionManager {
@@ -42,26 +45,30 @@ public class FailsafeExecutionManager implements ExecutionManager {
private final CircuitBreakerManager circuitBreakerManager;
private final RetryManager retryManager;
private final ExecutionPlanFactory executionPlanFactory;
private final ExecutorServiceProvider executorServiceProvider;

public FailsafeExecutionManager() {
FailsafeCircuitBreakerManager circuitBreakerManager = new FailsafeCircuitBreakerManager();
FailsafeRetryManager retryManager = new FailsafeRetryManager();
BulkheadManagerImpl bulkheadManager = new BulkheadManagerImpl();
this.mapper = MicroprofileAnnotationMapper.getInstance();
this.executionPlanFactory = new ExecutionPlanFactory(circuitBreakerManager, retryManager, bulkheadManager, mapper);
this.executorServiceProvider = new DefaultExecutorServiceProvider(Executors.newScheduledThreadPool(5));
this.executionPlanFactory = new ExecutionPlanFactory(circuitBreakerManager, retryManager, bulkheadManager, mapper,
executorServiceProvider);
this.circuitBreakerManager = circuitBreakerManager;
this.retryManager = retryManager;
this.bulkheadManager = bulkheadManager;
}

public FailsafeExecutionManager(MicroprofileAnnotationMapper mapper, BulkheadManagerImpl bulkheadManager,
FailsafeCircuitBreakerManager circuitBreakerManager, FailsafeRetryManager retryManager,
ExecutionPlanFactory executionPlanFactory) {
ExecutionPlanFactory executionPlanFactory, ExecutorServiceProvider executorServiceProvider) {
this.mapper = mapper;
this.bulkheadManager = bulkheadManager;
this.circuitBreakerManager = circuitBreakerManager;
this.retryManager = retryManager;
this.executionPlanFactory = executionPlanFactory;
this.executorServiceProvider = executorServiceProvider;
}

public Object execute(InvocationContext invocationContext) {
@@ -19,6 +19,7 @@

package org.apache.safeguard.impl.cdi;

import org.apache.safeguard.api.ExecutionManager;
import org.apache.safeguard.impl.FailsafeExecutionManager;

import javax.enterprise.context.ApplicationScoped;
@@ -28,6 +29,7 @@
public class FailsafeExecutionManagerProvider {
@Produces
@ApplicationScoped
private FailsafeExecutionManager failsafeExecutionManager = new FailsafeExecutionManager();

public ExecutionManager createExecutionManager() {
return new FailsafeExecutionManager();
}
}
@@ -28,6 +28,7 @@
import org.apache.safeguard.impl.circuitbreaker.FailsafeCircuitBreakerManager;
import org.apache.safeguard.api.config.ConfigFacade;
import org.apache.safeguard.impl.config.MicroprofileAnnotationMapper;
import org.apache.safeguard.impl.executorService.ExecutorServiceProvider;
import org.apache.safeguard.impl.fallback.FallbackRunner;
import org.apache.safeguard.impl.retry.FailsafeRetryBuilder;
import org.apache.safeguard.impl.retry.FailsafeRetryDefinition;
@@ -52,17 +53,20 @@ public class ExecutionPlanFactory {
private final FailsafeRetryManager retryManager;
private final BulkheadManager bulkheadManager;
private final MicroprofileAnnotationMapper microprofileAnnotationMapper;
private final ExecutorServiceProvider executorServiceProvider;
private ConcurrentMap<String, ExecutionPlan> executionPlanMap = new ConcurrentHashMap<>();
private final boolean enableAllMicroProfileFeatures;

public ExecutionPlanFactory(FailsafeCircuitBreakerManager circuitBreakerManager,
FailsafeRetryManager retryManager,
BulkheadManager bulkheadManager,
MicroprofileAnnotationMapper microprofileAnnotationMapper) {
MicroprofileAnnotationMapper microprofileAnnotationMapper,
ExecutorServiceProvider executorServiceProvider) {
this.circuitBreakerManager = circuitBreakerManager;
this.retryManager = retryManager;
this.bulkheadManager = bulkheadManager;
this.microprofileAnnotationMapper = microprofileAnnotationMapper;
this.executorServiceProvider = executorServiceProvider;
this.enableAllMicroProfileFeatures = this.enableNonFallbacksForMicroProfile();
}

@@ -100,16 +104,17 @@ public ExecutionPlan locateExecutionPlan(Method method) {
BulkheadExecutionPlan parent = new BulkheadExecutionPlan(bulkhead);
if (circuitBreaker == null && retryDefinition == null && isAsync) {
if (timeout == null) {
parent.setChild(new AsyncOnlyExecutionPlan(null));
parent.setChild(new AsyncOnlyExecutionPlan(executorServiceProvider.getExecutorService()));
} else {
parent.setChild(new AsyncTimeoutExecutionPlan(timeout, Executors.newFixedThreadPool(5)));
parent.setChild(new AsyncTimeoutExecutionPlan(timeout, executorServiceProvider.getExecutorService()));
}
} else if (circuitBreaker == null && retryDefinition == null && timeout != null) {
// then its just timeout
parent.setChild(new AsyncTimeoutExecutionPlan(timeout, Executors.newFixedThreadPool(5)));
parent.setChild(new AsyncTimeoutExecutionPlan(timeout, executorServiceProvider.getExecutorService()));
} else {
if (isAsync || timeout != null) {
parent.setChild(new AsyncFailsafeExecutionPlan(retryDefinition, circuitBreaker, fallbackRunner, Executors.newScheduledThreadPool(5), timeout));;
parent.setChild(new AsyncFailsafeExecutionPlan(retryDefinition, circuitBreaker, fallbackRunner,
executorServiceProvider.getScheduledExecutorService(), timeout));;
} else if(circuitBreaker == null && retryDefinition == null && fallbackRunner == null) {
parent.setChild(new BasicExecutionPlan());
} else if(circuitBreaker == null && retryDefinition == null) {
@@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.safeguard.impl.executorService;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;

public class DefaultExecutorServiceProvider implements ExecutorServiceProvider {
private final ScheduledExecutorService executorService;

public DefaultExecutorServiceProvider(ScheduledExecutorService executorService) {
this.executorService = executorService;
}

@Override
public ExecutorService getExecutorService() {
return executorService;
}

@Override
public ScheduledExecutorService getScheduledExecutorService() {
return executorService;
}
}
@@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.safeguard.impl.executorService;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;

/**
* Wraps the look up of an ExecutorService to handle SE and EE cases
*/
public interface ExecutorServiceProvider {
ExecutorService getExecutorService();
ScheduledExecutorService getScheduledExecutorService();
}

0 comments on commit 536d61e

Please sign in to comment.