dev.sixpack.generator.FactoryController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sdk Show documentation
Show all versions of sdk Show documentation
SDK to develop generators part of the Sixpack solution
The newest version!
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