![JAR search and dependency download from the Maven repository](/logo.png)
dev.sixpack.generator.FactoryController Maven / Gradle / Ivy
package dev.sixpack.generator;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import dev.sixpack.api.data.*;
import dev.sixpack.api.exception.IterateRequest;
import dev.sixpack.api.exception.NonRetryableException;
import io.temporal.workflow.Workflow;
import java.time.Duration;
import org.slf4j.Logger;
import java.lang.reflect.InvocationTargetException;
import java.time.Instant;
public class FactoryController {
public static final Integer MAX_RETRIES = 5;
public static final Duration INITIAL_INTERVAL = Duration.ofSeconds(5);
public static final Integer BACKOFF_COEFFICIENT = 2;
public static final Duration MAXIMUM_INTERVAL = Duration.ofMinutes(1);
private final static ObjectMapper MAPPER = new ObjectMapper();
static {
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
MAPPER.registerModule(new JavaTimeModule());
}
/**
* This method must be called from Workflows only. It will handle retries since they don't work as expected
*
* @return
*/
public static Result generateWithRetries(Request request, Logger LOGGER, FactoryRecord factoryRecord) {
int attempt = 1;
Duration interval = INITIAL_INTERVAL;
while (true) {
LOGGER.debug("Executing orchestrator, attempt: " + attempt);
try {
return generate(request, LOGGER, factoryRecord);
} catch (Exception e) {
if (attempt >= MAX_RETRIES) {
LOGGER.debug("Orchestrator {} with configuration {} failed", request.getItemName(), request.getInput());
return Result.failed(e.getMessage(), request.getContextMap());
}
LOGGER.error("Exception occurred in orchestrator {}, configuration {}. Retrying in {} s",
request.getItemName(),
request.getInput(),
interval.getSeconds(),
e);
Workflow.sleep(interval);
attempt++;
// increase interval
interval = interval.multipliedBy(BACKOFF_COEFFICIENT);
if (interval.compareTo(MAXIMUM_INTERVAL) > 0) {
interval = MAXIMUM_INTERVAL;
}
}
}
}
/**
* Main generation method.
* It will return a Result if generation is successful, or if NonRetriable or IterateRequest exceptions were thrown during
* generator/orchestrator generate method execution
* If other exception is thrown during Factory.generate() method, it will not be caught
*
* @param request Request coming from Sixpack backend through temporal
* @return Result which may represent success, failure or iteration request
*/
public static Result generate(Request request, Logger LOGGER, FactoryRecord factoryRecord) {
String itemName = request.getItemName();
Configuration input = request.getInput();
Object generatorInput = MAPPER.convertValue(input, factoryRecord.getInput());
int iteration = request.getIteration();
JMap configuration = request.getContextMap() != null ? request.getContextMap() : new JMap();
Context context = new Context(iteration, configuration);
LOGGER.debug("Generating {} with configuration {} iteration {}",
itemName,
generatorInput,
iteration);
try {
FactoryInterface factory = getFactory(factoryRecord, request.getId());
Object factoryOutput = factory.generate(generatorInput, context);
LOGGER.debug("Sending back final output {}", factoryOutput);
Configuration output = MAPPER.convertValue(factoryOutput, Configuration.class);
LOGGER.debug("Sending back with status OK");
return new Result(ResultStatus.OK,
null,
null,
null,
output,
Instant.now());
} catch (IterateRequest iterateRequest) {
LOGGER.debug("Next iteration requested after {} with message {}",
iterateRequest.getTimeout(),
iterateRequest.getMessage());
return new Result(ResultStatus.ITERATE,
iterateRequest.getMessage(),
context.getDetails(),
Instant.now().plus(iterateRequest.getTimeout()),
null,
Instant.now());
} catch (NonRetryableException e) {
return Result.failed(e.getMessage(), context.getDetails());
}
}
private static FactoryInterface getFactory(FactoryRecord factoryRecord, String id) {
Generator generator = factoryRecord.getGenerator();
if (generator != null) {
return generator;
} else {
try {
Orchestrator orchestrator = factoryRecord.getOrchestrator().getDeclaredConstructor().newInstance();
orchestrator.setEnvironment(factoryRecord.getEnvironment());
orchestrator.setDatasetId(id);
return orchestrator;
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy