### Start Node Protocol Source: https://github.com/alibaba/compileflow/wiki/协议详解 Defines the starting point of a process. Includes transitions to the next node using the 'to' attribute. ```xml ``` -------------------------------- ### ProcessEngine.admin Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Gets the administration service, used for deploying and warming up processes. ```APIDOC ## `ProcessEngine.admin()` ### Description Gets the administration service, used for deploying and warming up processes. ### Method ```java ProcessAdminService admin(); ``` ``` -------------------------------- ### ProcessEngine.execute Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Executes a stateless process from start to finish. This is the most common execution method. ```APIDOC ## `ProcessEngine.execute` (for Stateless Processes) ### Description Used to execute a stateless process from start to finish. This is the most common execution method. ### Method ```java // Method 1: Type-Safe DTOs ProcessResult execute(ProcessSource source, I input, Class outputType); // Method 2: Flexible Map ProcessResult> execute(ProcessSource source, Map context); ``` ``` -------------------------------- ### Process Engine Start Execution Source: https://github.com/alibaba/compileflow/wiki/协议详解 Java code snippet to start a process execution using the ProcessEngineFactory. Requires the process code and a context map. ```java Map result = ProcessEngineFactory.getProcessEngine().start(code, context); ``` -------------------------------- ### Spring Boot Application Entry Point Source: https://github.com/alibaba/compileflow/blob/master/docs/en/quick-start.md Standard Spring Boot application class to run the application. No specific CompileFlow setup is needed here. ```java package com.example.ktv; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class KtvApplication { public static void main(String[] args) { SpringApplication.run(KtvApplication.class, args); } } ``` -------------------------------- ### ProcessEngine.tooling Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Gets the tooling service, used for code generation and model inspection. ```APIDOC ## `ProcessEngine.tooling()` ### Description Gets the tooling service, used for code generation and model inspection. ### Method ```java ProcessToolingService tooling(); ``` ``` -------------------------------- ### Warm up Processes with ProcessAdminService Source: https://github.com/alibaba/compileflow/blob/master/docs/en/advanced-features.md Pre-compiles and caches flows to eliminate first hit latency. This should be done when your application starts. ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Service; @Service public class FlowPreheatingService implements ApplicationRunner { @Autowired private ProcessEngine processEngine; @Override public void run(ApplicationArguments args) throws Exception { // Automatically warm up all critical processes after the application starts // The deploy method compiles the process and caches the result, overwriting if it already exists processEngine.admin().deploy( ProcessSource.fromCode("bpm.order.process"), ProcessSource.fromCode("bpm.payment.process"), ProcessSource.fromCode("bpm.user.profile.process") // ... add more processes to warm up ); } } ``` -------------------------------- ### Execute Stateless Process Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Used to execute a stateless process from start to finish. Supports type-safe DTOs or flexible Maps for input and output. ```java ProcessResult execute(ProcessSource source, I input, Class outputType); ``` ```java ProcessResult> execute(ProcessSource source, Map context); ``` -------------------------------- ### Clone CompileFlow Repository Source: https://github.com/alibaba/compileflow/blob/master/docs/en/contributing.md Clone the forked CompileFlow repository to your local machine to start making changes. ```bash git clone https://github.com/YOUR_USERNAME/compileflow.git ``` -------------------------------- ### Spring Boot Configuration for CompileFlow Metrics Source: https://github.com/alibaba/compileflow/blob/master/docs/en/monitoring.md Configure CompileFlow's observability and custom metrics in application.yml. This example shows how to enable global observability and a specific custom metrics listener. ```yaml compileflow: observability: enabled: true # This must be true globally custom-metrics: enabled: true # This is your custom toggle for this specific listener management: endpoints: web: exposure: include: "prometheus,health" ``` -------------------------------- ### ProcessEngine.trigger Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Drives a stateful process (a state machine) that has already been started and is in a wait state. ```APIDOC ## `ProcessEngine.trigger` (for Stateful Processes) ### Description Used to drive a stateful process (a state machine) that has already been started and is in a wait state. ### Method ```java // Method 1: With event and Type-Safe DTOs ProcessResult trigger(ProcessSource source, String tag, String event, E payload, Class outputType); // Method 2: With event and Map ProcessResult> trigger(ProcessSource source, String tag, String event, Map context); // Method 3: Without event and Type-Safe DTOs (event is null) ProcessResult trigger(ProcessSource source, String tag, E payload, Class outputType); // Method 4: Without event and Map (event is null) ProcessResult> trigger(ProcessSource source, String tag, Map context); ``` ### Parameters - **`tag`** (String) - Required - The unique identifier of a wait node (e.g., `waitTask`) in the process definition. - **`event`** (String) - Optional - An optional event identifier to distinguish different trigger paths on the same wait node. ``` -------------------------------- ### AutoTask Node Execution Example Source: https://github.com/alibaba/compileflow/wiki/协议详解 Generated Java code for an AutoTask node executing a Spring Bean method. It demonstrates method invocation with parameter mapping. ```java //AutoTaskNode: 付款 ((MockSpringBean)BeanProvider.getBean("mockSpringBean")).payMoney(price); ``` -------------------------------- ### ScriptTask Node Java Code Generation Source: https://github.com/alibaba/compileflow/wiki/协议详解 Generated Java code for a ScriptTask node executing a 'QL' expression. It shows the setup of the expression context and execution. ```java //ScriptTaskNode: 原价 IExpressContext nfScriptContext = new DefaultContext<>(); nfScriptContext.put("price", totalPrice); price = (java.lang.Integer)ScriptExecutorProvider.getInstance().getScriptExecutor("QL").execute("price*1", nfScriptContext); ``` -------------------------------- ### ProcessResult Core Methods Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Provides core methods to check execution status, retrieve data or error messages, and get the trace ID. ```java boolean isSuccess(); ``` ```java T getData(); ``` ```java String getErrorMessage(); ``` ```java String getTraceId(); ``` -------------------------------- ### Application Startup and Execution with Singleton Engine Source: https://github.com/alibaba/compileflow/blob/master/README.md Demonstrates how to initialize the singleton engine at application startup, deploy processes, execute them during business logic, and register a shutdown hook to ensure proper resource cleanup. This pattern is crucial for long-running applications. ```java public class YourApplication { public static void main(String[] args) { // At application startup, you can warm-up processes ProcessEngineHolder.getInstance().admin().deploy(ProcessSource.fromCode("...")); // In your business logic, get the singleton instance ProcessEngine engine = ProcessEngineHolder.getInstance(); engine.execute(...); // Register a shutdown hook to ensure resources are released Runtime.getRuntime().addShutdownHook(new Thread(ProcessEngineHolder::shutdown)); } } ``` -------------------------------- ### Process Version Management Strategies Source: https://github.com/alibaba/compileflow/blob/master/docs/en/advanced-features.md Demonstrates three common strategies for managing process versions: using distinct codes, loading dynamic content, or utilizing different file paths. Strategy 1 is simple, Strategy 2 is for dynamic updates, and Strategy 3 is for file-based storage. ```java // Strategy 1: Use different codes to distinguish versions (simple and clear) ProcessSource v1 = ProcessSource.fromCode("bpm.order.process.v1"); ProcessSource v2 = ProcessSource.fromCode("bpm.order.process.v2"); engine.execute(v2, ...); // Strategy 2: Load different content for the same code (useful for dynamic updates) String contentV2 = loadFlowWithVersionFromDatabase("bpm.order.process", "v2"); ProcessSource source = ProcessSource.fromContent("bpm.order.process", contentV2); engine.execute(source, ...); // Overwrites the cache entry for "bpm.order.process" // Strategy 3: Use different file paths (good for file-based storage) ProcessSource v1File = ProcessSource.fromFile("bpm.order.process", "/flows/v1/order.bpm"); ProcessSource v2File = ProcessSource.fromFile("bpm.order.process", "/flows/v2/order.bpm"); // Note: fromFile uses the code to key the cache, so v2File will overwrite v1File. // For parallel versions with file-based loading, use distinct codes. ``` -------------------------------- ### Create ProcessSource from Filesystem Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Loads a process definition from a specified file path on the filesystem. ```java static ProcessSource fromFile(String code, String filePath); ``` ```java static ProcessSource fromFile(String code, File file); ``` -------------------------------- ### Create ProcessSource from Classpath Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Loads a process definition from the classpath. This is the recommended method for process sourcing. ```java static ProcessSource fromCode(String code); ``` -------------------------------- ### Spring Boot: Injecting a Singleton ProcessEngine Source: https://github.com/alibaba/compileflow/blob/master/docs/en/resource-management.md This is the recommended approach for Spring Boot applications. It shows how to inject a pre-configured singleton ProcessEngine managed by the Spring framework, ensuring efficient resource reuse and proper lifecycle management. ```java import com.alibaba.compileflow.engine.ProcessEngine; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class OrderService { // ✅ CORRECT: Inject the singleton engine managed by Spring. @Autowired private ProcessEngine engine; public void processOrder(OrderRequest request) { // Safe and efficient: all requests share the same engine and thread pools. engine.execute(ProcessSource.fromCode("bpm.order.process"), request, OrderResponse.class); } } ``` -------------------------------- ### Deploy Processes with ProcessAdminService Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Deploys one or more processes, triggering compilation and caching. Recommended for application startup and engine warm-up. ```java void deploy(ProcessSource... sources); ``` ```java void deploy(ClassLoader loader, ProcessSource... sources); ``` -------------------------------- ### Manual Singleton: Managing ProcessEngine Lifecycle Source: https://github.com/alibaba/compileflow/blob/master/docs/en/resource-management.md For non-Spring applications, this pattern demonstrates how to create and manage a single ProcessEngine instance manually. It includes registering a JVM shutdown hook to ensure the engine is closed gracefully upon application exit. ```java import com.alibaba.compileflow.engine.ProcessEngine; import com.alibaba.compileflow.engine.ProcessEngineFactory; import com.alibaba.compileflow.engine.config.ProcessEngineConfig; public final class ProcessEngineManager { // ✅ CORRECT: Create a single, static instance. private static final ProcessEngine INSTANCE = ProcessEngineFactory.create(ProcessEngineConfig.tbbpm()); static { // ✅ CRITICAL: Register a shutdown hook to close the engine on exit. Runtime.getRuntime().addShutdownHook(new Thread(() -> { try { INSTANCE.close(); System.out.println("ProcessEngine shut down gracefully."); } catch (Exception e) { System.err.println("Error shutting down ProcessEngine: " + e.getMessage()); } })); } public static ProcessEngine getInstance() { return INSTANCE; } private ProcessEngineManager() {} } ``` -------------------------------- ### Create ProcessSource from URL Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Loads a process definition from a URL. ```java static ProcessSource fromUrl(String code, String url); ``` ```java static ProcessSource fromUrl(String code, URL url); ``` -------------------------------- ### Enable INFO Logging for Configuration Verification Source: https://github.com/alibaba/compileflow/blob/master/docs/en/configuration.md YAML snippet to enable INFO level logging for the ProcessEngineAutoConfiguration class. This allows verification of effective runtime configuration settings. ```yaml logging: level: com.alibaba.compileflow.engine.spring.boot.autoconfigure.ProcessEngineAutoConfiguration: INFO ``` -------------------------------- ### ProcessAdminService.deploy Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Deploys one or more processes, triggering compilation and caching. ```APIDOC ## `ProcessAdminService.deploy` ### Description Deploy one or more processes. This triggers the compilation and caching of the process. Call this at application startup for engine warm-up. ### Method ```java // Deploy one or more processes. void deploy(ProcessSource... sources); // Deploy processes with a specific ClassLoader void deploy(ClassLoader loader, ProcessSource... sources); ``` ``` -------------------------------- ### Try-with-Resources: Temporary ProcessEngine for Batch Jobs Source: https://github.com/alibaba/compileflow/blob/master/docs/en/resource-management.md This snippet illustrates the use of a try-with-resources block for creating a temporary ProcessEngine, suitable for short-lived tasks like integration tests or batch jobs. This ensures the engine is automatically closed after use, preventing resource leaks. ```java import com.alibaba.compileflow.engine.ProcessEngine; import com.alibaba.compileflow.engine.ProcessEngineFactory; public class BatchProcessor { public void processBatch(List items) { // ✅ CORRECT: The engine is guaranteed to be closed at the end of the block. try (ProcessEngine engine = ProcessEngineFactory.createTbbpm()) { for (Item item : items) { engine.execute(ProcessSource.fromCode("batch.item.process"), item, Result.class); } } // engine.close() is automatically called here. } } ``` -------------------------------- ### File System Monitoring for Hot Deployment Source: https://github.com/alibaba/compileflow/blob/master/docs/en/hot-deploy.md Automate hot deployments by monitoring a specified directory for changes. This is useful for local development and production environments with shared file systems. ```java import com.alibaba.compileflow.engine.deploy.FlowHotDeployer; import com.alibaba.compileflow.engine.deploy.detector.FileSystemChangeDetector; // Assume 'engine' is an initialized ProcessEngine instance // Monitor a production directory for changes FileSystemChangeDetector detector = new FileSystemChangeDetector("/opt/flows"); FlowHotDeployer hotDeployer = new FlowHotDeployer(engine.admin(), detector); hotDeployer.start(); // Starts the monitoring in a background thread // To stop monitoring: // hotDeployer.stop(); ``` -------------------------------- ### Create ProcessSource from Classpath Resource Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Loads a process definition from a specific resource path within the classpath. ```java static ProcessSource fromClasspath(String code, String resourcePath); ``` -------------------------------- ### Programmatic Configuration Workaround for Observability Source: https://github.com/alibaba/compileflow/blob/master/docs/en/monitoring.md Use system properties as a workaround for enabling CompileFlow's observability features programmatically. This is useful when direct programmatic configuration is not yet available. ```java // Not yet available via programmatic config. Use system properties as a workaround: // -Dcompileflow.observability.enabled=true // -Dcompileflow.observability.events-async=true ``` -------------------------------- ### Register Extension Realizations via SPI Source: https://github.com/alibaba/compileflow/blob/master/docs/en/extension-guide.md Register implementation classes in a file named after the fully qualified interface name under META-INF/extensions/. ```properties com.example.extensions.impl.StandardPricePolicy com.example.extensions.impl.BulkDiscountPolicy ``` -------------------------------- ### Programmatic Engine Configuration Source: https://github.com/alibaba/compileflow/blob/master/docs/en/configuration.md Configure a TBBPM engine with specific compilation and execution threads programmatically. Use try-with-resources for proper lifecycle management. ```java import com.alibaba.compileflow.engine.ProcessEngine; import com.alibaba.compileflow.engine.ProcessEngineFactory; import com.alibaba.compileflow.engine.config.ProcessEngineConfig; import com.alibaba.compileflow.engine.config.ProcessExecutorConfig; // Example: Configure a TBBPM engine with 4 compilation and 32 execution threads. ProcessEngineConfig config = ProcessEngineConfig.tbbpmBuilder() .parallelCompilation(true) .executors(ProcessExecutorConfig.of(4, 32)) // More explicit than .threads() .build(); // Use try-with-resources to ensure the engine is closed properly. try (ProcessEngine engine = ProcessEngineFactory.create(config)) { // Your business logic here... // For example: engine.execute(...) } catch (Exception e) { // Handle exceptions } ``` -------------------------------- ### Development Profile Configuration Source: https://github.com/alibaba/compileflow/blob/master/docs/en/configuration.md YAML configuration for a development environment, prioritizing fast startup and low resource usage by limiting threads and disabling observability. ```yaml compileflow: executor: compilation-threads: 1 execution-threads: 4 cache: runtime-max-size: 200 # Smaller cache to save memory observability: enabled: false # Disable for faster startup ``` -------------------------------- ### ProcessToolingService Methods Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Methods for loading and generating process source code. Use `loadFlowModel` for in-memory inspection and `generateJavaCode` for debugging. ```java // Parse a process source into an in-memory FlowModel object for inspection and analysis T loadFlowModel(ProcessSource processSource); // Generate the underlying Java source code from a process source for debugging String generateJavaCode(ProcessSource processSource); ``` -------------------------------- ### Implement Extension Realizations with Priority Source: https://github.com/alibaba/compileflow/blob/master/docs/en/extension-guide.md Implement the PricePolicy interface with @ExtensionRealization annotation. Higher priority values indicate a preferred implementation. ```java package com.example.extensions.impl; import com.alibaba.compileflow.engine.core.extension.ExtensionRealization; import com.example.extensions.PricePolicy; @ExtensionRealization(priority = 100) // Higher priority is preferred public class StandardPricePolicy implements PricePolicy { @Override public int calculatePrice(int quantity, int basePrice) { return quantity * basePrice; } } @ExtensionRealization(priority = 50) public class BulkDiscountPolicy implements PricePolicy { @Override public int calculatePrice(int quantity, int basePrice) { int total = quantity * basePrice; return quantity >= 10 ? (int)(total * 0.9) : total; // 10% discount for 10+ items } } ``` -------------------------------- ### Create ProcessSource from XML Content Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Loads a process definition directly from an XML string content. ```java static ProcessSource fromContent(String code, String xmlContent); ``` -------------------------------- ### Implement Custom ProcessEngineProvider Source: https://github.com/alibaba/compileflow/blob/master/docs/en/extension-guide.md Create a custom provider for a specific FlowModelType by implementing ProcessEngineProvider. This is used for plugging in fundamental new functionality. ```java package com.example.engine; import com.alibaba.compileflow.engine.ProcessEngineProvider; import com.alibaba.compileflow.engine.common.FlowModelType; import com.alibaba.compileflow.engine.core.AbstractProcessEngine; import com.alibaba.compileflow.engine.config.ProcessEngineConfig; // A custom provider for the TBBPM model type public class CustomTbbpmEngineProvider implements ProcessEngineProvider { @Override public FlowModelType support() { return FlowModelType.TBBPM; } @Override public AbstractProcessEngine createEngine(ProcessEngineConfig config) { // Return your custom subclass of AbstractProcessEngine return new MyCustomTbbpmEngine(config); } } ``` -------------------------------- ### ProcessToolingService Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Provides tools for parsing and analyzing process sources, and generating Java code from them. ```APIDOC ## ProcessToolingService Accessed via `engine.tooling()`. ### Methods - **loadFlowModel** - Description: Parse a process source into an in-memory FlowModel object for inspection and analysis. - Parameters: - `processSource` (ProcessSource) - Description: The source of the process to load. - Returns: `FlowModel` - **generateJavaCode** - Description: Generate the underlying Java source code from a process source for debugging. - Parameters: - `processSource` (ProcessSource) - Description: The source of the process to generate code from. - Returns: `String` ``` -------------------------------- ### Inject and Execute Process with Spring Boot Source: https://github.com/alibaba/compileflow/blob/master/README.md Inject the ProcessEngine into your service and use it to execute a business process. The ProcessEngine is auto-configured as a singleton. Handle potential runtime exceptions by checking the ProcessResult. ```java @Service public class BusinessService { @Autowired private ProcessEngine processEngine; public MyResponse executeProcess(MyRequest request) { ProcessSource processSource = ProcessSource.fromCode("my.business.process"); ProcessResult result = processEngine.execute( processSource, request, MyResponse.class ); return result.orElseThrow(() -> new RuntimeException(result.getErrorMessage())); } } ``` -------------------------------- ### Register Custom ProcessEngineProvider via SPI Source: https://github.com/alibaba/compileflow/blob/master/docs/en/extension-guide.md Register the custom provider class in the META-INF/services/com.alibaba.compileflow.engine.ProcessEngineProvider file. ```properties com.example.engine.CustomTbbpmEngineProvider ``` -------------------------------- ### ProcessEngineFactory Creation Methods Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Factory methods for creating `ProcessEngine` instances. Use `createTbbpm` for TBBPM engines, `createBpmn` for BPMN engines, and `create` for custom configurations. ```java // Create a TBBPM engine with default configuration static ProcessEngine createTbbpm(); // Create a BPMN engine with default configuration static ProcessEngine createBpmn(); // Create an engine from a detailed configuration object static ProcessEngine create(ProcessEngineConfig config); ``` -------------------------------- ### Inspect Process Models and Generate Java Code Source: https://github.com/alibaba/compileflow/blob/master/docs/en/advanced-features.md Uses the ProcessToolingService to load flow models for analysis and generate Java source code for debugging. ```java // Get tooling service from engine ProcessToolingService tooling = engine.tooling(); // 1. Load process model for analysis TbbpmModel model = tooling.loadFlowModel(ProcessSource.fromCode("bpm.order.process")); System.out.println("Process name: " + model.getName()); System.out.println("Start node: " + model.getStartNode().getId()); // 2. Generate Java source code for debugging String javaCode = tooling.generateJavaCode(ProcessSource.fromCode("bpm.order.process")); System.out.println("Generated Java code:\n" + javaCode); ``` -------------------------------- ### Implement a Basic Process Completion Listener Source: https://github.com/alibaba/compileflow/blob/master/docs/en/monitoring.md Create a Java class that implements the ProcessEventListener interface to log process completion events. This listener logs the process code and its duration when execution is completed. ```java package com.example.listeners; import com.alibaba.compileflow.engine.core.event.*; import com.alibaba.compileflow.engine.core.extension.ExtensionRealization; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // @ExtensionRealization is optional but recommended for clarity. // The primary discovery mechanism is the SPI file. @ExtensionRealization public class SimpleProcessLogger implements ProcessEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleProcessLogger.class); @Override public void onEvent(ProcessEvent event) { // Use instanceof for type-safe event handling if (event instanceof ProcessCoreEvents.ExecutionCompleted) { ProcessCoreEvents.ExecutionCompleted completedEvent = (ProcessCoreEvents.ExecutionCompleted) event; LOGGER.info("Process [{}] completed in {}ms.", completedEvent.getProcessCode(), completedEvent.getContext().getDurationMs()); } } } ``` -------------------------------- ### Add CompileFlow Spring Boot Starter Dependency Source: https://github.com/alibaba/compileflow/blob/master/README.md Include this dependency in your pom.xml to use CompileFlow with Spring Boot. Ensure you use the correct version. ```xml com.alibaba.compileflow compileflow-spring-boot-starter 2.0.0-SNAPSHOT ``` -------------------------------- ### Register Event Listener via SPI Source: https://github.com/alibaba/compileflow/blob/master/docs/en/extension-guide.md Register your custom ProcessEventListener by creating a file in META-INF/extensions and listing the fully qualified name of your listener class. ```text com.example.listeners.AuditLoggerListener ``` -------------------------------- ### Create a New Feature Branch Source: https://github.com/alibaba/compileflow/blob/master/docs/en/contributing.md Create a new branch for your feature development, ensuring a descriptive name. ```bash git checkout -b feature/your-awesome-feature-name ``` -------------------------------- ### ProcessEngineFactory Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Used to create ProcessEngine instances in non-Spring environments. ```APIDOC ## ProcessEngineFactory Used to create `ProcessEngine` instances in non-Spring environments. ### Methods - **createTbbpm** - Description: Create a TBBPM engine with default configuration. - Returns: `ProcessEngine` - **createBpmn** - Description: Create a BPMN engine with default configuration. - Returns: `ProcessEngine` - **create** - Description: Create an engine from a detailed configuration object. - Parameters: - `config` (ProcessEngineConfig) - Description: The configuration object for the engine. - Returns: `ProcessEngine` where T extends `FlowModel` ``` -------------------------------- ### Add CompileFlow Core and Specification Dependencies (Standalone) Source: https://github.com/alibaba/compileflow/blob/master/README.md For non-Spring applications, add the core dependency and the dependency for your chosen process specification (e.g., tbbpm or bpmn). ```xml com.alibaba.compileflow compileflow-core 2.0.0-SNAPSHOT com.alibaba.compileflow compileflow-tbbpm 2.0.0-SNAPSHOT ``` -------------------------------- ### Invoke Extension with Highest Priority Source: https://github.com/alibaba/compileflow/blob/master/docs/en/extension-guide.md Use ExtensionInvoker.invokeFirst to automatically select and execute the implementation with the highest priority. ```java import com.alibaba.compileflow.engine.core.extension.ExtensionInvoker; import com.example.extensions.PricePolicy; int quantity = 15; int basePrice = 100; // The invoker finds all PricePolicy realizations, selects the one with the // highest priority (StandardPricePolicy, since 100 > 50), and executes the lambda against it. int finalPrice = ExtensionInvoker.getInstance().invokeFirst( "price.policy.calculate", (PricePolicy policy) -> policy.calculatePrice(quantity, basePrice) ); // The ExtensionInvoker also offers other patterns like invokeAll, invokeChain, etc. ``` -------------------------------- ### KTV Billing Service Implementation Source: https://github.com/alibaba/compileflow/blob/master/docs/en/quick-start.md This Java service class uses CompileFlow's `ProcessEngine` to execute a business process for calculating KTV billing. It defines type-safe request and response DTOs and handles process execution and error management. ```java package com.example.ktv.service; import com.alibaba.compileflow.engine.ProcessEngine; import com.alibaba.compileflow.engine.ProcessResult; import com.alibaba.compileflow.engine.ProcessSource; import com.alibaba.compileflow.engine.tbbpm.definition.TbbpmModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class KtvBillingService { @Autowired private ProcessEngine processEngine; // Define an input DTO for type-safe interaction public static class KtvRequest { // The field name "pList" must match the in the process definition public List pList; } // Define an output DTO for type-safe interaction public static class KtvResponse { // The field name "price" must match the in the process definition public Integer price; } /** * Executes the KTV billing process. */ public KtvResponse calculatePrice(List customers) { KtvRequest request = new KtvRequest(); request.pList = customers; // 1. Create the ProcessSource from its unique code ProcessSource source = ProcessSource.fromCode("bpm.ktv.quickstart"); // 2. Execute the process, passing the request DTO and specifying the response DTO type ProcessResult result = processEngine.execute( source, request, KtvResponse.class ); // 3. Check the result. If it failed, throw an exception; otherwise, return the data. if (result.isSuccess()) { return result.getData(); } else { throw new RuntimeException("KTV billing process execution failed: " + result.getErrorMessage()); } } } ``` -------------------------------- ### Test Case 1: Standard Price JSON Response Source: https://github.com/alibaba/compileflow/blob/master/docs/en/quick-start.md This JSON response shows the calculated price for a group of 3 customers, based on the standard pricing rule. ```json { "price": 90 } ``` -------------------------------- ### KTV Billing Process Definition (BPMN) Source: https://github.com/alibaba/compileflow/blob/master/docs/en/quick-start.md Defines a KTV billing process with decision logic based on group size. The process uses variables for pricing and group lists, and includes script tasks for price calculation. ```xml ``` -------------------------------- ### Integrating External Services with autoTask Source: https://github.com/alibaba/compileflow/blob/master/docs/en/advanced-features.md Shows how to call external services from CompileFlow processes using the `autoTask` element. This includes calling Spring Beans and static Java methods. ```xml ``` -------------------------------- ### Registering CompileFlow Listener via SPI Source: https://github.com/alibaba/compileflow/blob/master/docs/en/monitoring.md Add the MicrometerMetricsListener to the SPI extensions file to enable it for CompileFlow. This method is used when not integrating with a DI framework like Spring. ```text com.example.listeners.SimpleProcessLogger com.example.listeners.MicrometerMetricsListener ``` -------------------------------- ### Access Process Services Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Provides access to administrative and tooling services for managing and inspecting processes. ```java ProcessAdminService admin(); ``` ```java ProcessToolingService tooling(); ``` -------------------------------- ### 95th Percentile Execution Time for Successful Processes Source: https://github.com/alibaba/compileflow/blob/master/docs/en/monitoring.md Calculates the 95th percentile of execution time for successful CompileFlow processes over a 5-minute window, grouped by process code. This query helps identify performance bottlenecks in successful executions. ```promql # 95th percentile execution time for successful processes, grouped by code histogram_quantile(0.95, sum(rate(compileflow_execution_duration_seconds_bucket{status="success"}[5m])) by (le, process_code)) ``` -------------------------------- ### Anti-pattern: Creating ProcessEngine in a Request Handler Source: https://github.com/alibaba/compileflow/blob/master/docs/en/resource-management.md This code snippet demonstrates an anti-pattern where a new ProcessEngine is created for each request, leading to severe resource leaks. Avoid this approach. ```java // ❌ ANTI-PATTERN: DO NOT DO THIS! public void handleRequest(Request request) { // Each call creates 16-64 new threads that will never be cleaned up! ProcessEngine engine = ProcessEngineFactory.createTbbpm(); engine.execute(source, request, Response.class); } ``` -------------------------------- ### Configure Engine with Custom ClassLoader Source: https://github.com/alibaba/compileflow/blob/master/docs/en/advanced-features.md Provides a custom ClassLoader to the engine for loading external process definitions or dependencies. This is useful when JARs are loaded from external locations. ```java import java.io.File; import java.net.URL; import java.net.URLClassLoader; // Create custom ClassLoader ClassLoader customClassLoader = new URLClassLoader(new URL[]{ new File("/opt/flows/lib").toURI().toURL() }); // Use engine with custom ClassLoader ProcessEngineConfig config = ProcessEngineConfig.tbbpmBuilder() .classLoader(customClassLoader) .build(); try (ProcessEngine engine = ProcessEngineFactory.create(config)) { ProcessResult> result = engine.execute(source, context); } ``` -------------------------------- ### Implement Human Task with waitTask Source: https://github.com/alibaba/compileflow/blob/master/docs/en/node-support.md Use the waitTask node as an alternative to userTask for human task functionality. This snippet shows the XML configuration for the waitTask. ```xml ``` -------------------------------- ### ProcessResult Convenience Methods Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Convenience methods for simplified result handling. ```APIDOC ## `ProcessResult` Convenience Methods ### Description `ProcessResult` provides a rich set of functional-style methods to simplify result handling. ### Methods ```java // Returns the value on success or a default value on failure T orElse(T defaultValue); // Returns the value on success or executes a Supplier for a fallback value on failure T orElseGet(Supplier supplier); // Returns the value on success or throws an exception on failure T orElseThrow(); T orElseThrow(Supplier exceptionSupplier) throws X; // Perform an action with the data on success ProcessResult onSuccess(Consumer action); // Perform an action with the error message on failure ProcessResult onFailure(Consumer action); // Transform the data of a successful result ProcessResult map(Function mapper); ``` ``` -------------------------------- ### CompileFlow Process Throughput Analysis Source: https://github.com/alibaba/compileflow/blob/master/docs/en/monitoring.md Measures the throughput of CompileFlow processes in executions per second over a 5-minute window, aggregated by process code. This is useful for understanding the load on individual processes. ```promql # Throughput (executions per second) grouped by process code sum(rate(compileflow_execution_duration_seconds_count[5m])) by (process_code) ``` -------------------------------- ### ProcessResult Convenience Methods Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Offers functional-style methods for simplified result handling, including default values, exception throwing, and conditional actions. ```java T orElse(T defaultValue); ``` ```java T orElseGet(Supplier supplier); ``` ```java T orElseThrow(); ``` ```java T orElseThrow(Supplier exceptionSupplier) throws X; ``` ```java ProcessResult onSuccess(Consumer action); ``` ```java ProcessResult onFailure(Consumer action); ``` ```java ProcessResult map(Function mapper); ``` -------------------------------- ### Emergency Rollback to Stable Version Source: https://github.com/alibaba/compileflow/blob/master/docs/en/hot-deploy.md Perform an emergency rollback by hot-deploying a known stable version of a process definition. This allows for quick recovery from issues introduced by recent deployments. ```java import com.alibaba.compileflow.engine.ProcessEngine; import com.alibaba.compileflow.engine.ProcessSource; // Assume 'engine' is an initialized ProcessEngine instance and 'stableVersionXml' contains the XML content of the stable version // engine.admin().deploy(ProcessSource.fromContent("bpm.order.process", stableVersionXml)); ``` -------------------------------- ### Test Case 1: Standard Price JSON Request Source: https://github.com/alibaba/compileflow/blob/master/docs/en/quick-start.md This JSON payload represents a group of 3 customers, which should trigger the standard pricing logic in the KTV billing process. ```json ["customer1", "customer2", "customer3"] ``` -------------------------------- ### KTV Billing API Controller Source: https://github.com/alibaba/compileflow/blob/master/docs/en/quick-start.md This Spring Boot controller exposes a REST endpoint to calculate KTV billing prices. It injects the `KtvBillingService` and handles POST requests to the `/calculate` path. ```java package com.example.ktv.controller; import com.example.ktv.service.KtvBillingService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class KtvController { @Autowired private KtvBillingService ktvBillingService; @PostMapping("/calculate") public KtvBillingService.KtvResponse calculate(@RequestBody List customers) { return ktvBillingService.calculatePrice(customers); } } ``` -------------------------------- ### Micrometer Metrics Listener for CompileFlow Source: https://github.com/alibaba/compileflow/blob/master/docs/en/monitoring.md Implement a ProcessEventListener to capture CompileFlow execution and compilation events and record them using Micrometer. This listener records execution durations and compilation failures. ```java package com.example.listeners; import com.alibaba.compileflow.engine.core.event.*; import com.alibaba.compileflow.engine.core.extension.ExtensionRealization; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; import java.util.concurrent.TimeUnit; @ExtensionRealization public class MicrometerMetricsListener implements ProcessEventListener { private final MeterRegistry meterRegistry; // In a real application, inject MeterRegistry via your DI framework. // For this example, we assume it's passed in. public MicrometerMetricsListener(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; } @Override public void onEvent(ProcessEvent event) { String processCode = event.getProcessCode(); ProcessEventContext context = event.getContext(); if (event instanceof ProcessCoreEvents.ExecutionCompleted) { Timer.builder("compileflow.execution.duration") .description("Process execution duration") .tag("process.code", processCode) .tag("status", "success") .register(meterRegistry) .record(context.getDurationMs(), TimeUnit.MILLISECONDS); } else if (event instanceof ProcessCoreEvents.ExecutionFailed) { Timer.builder("compileflow.execution.duration") .description("Process execution duration") .tag("process.code", processCode) .tag("status", "failure") .register(meterRegistry) .record(context.getDurationMs(), TimeUnit.MILLISECONDS); } else if (event instanceof ProcessCoreEvents.CompilationFailed) { Counter.builder("compileflow.compilation.failures") .description("Process compilation failures") .tag("process.code", processCode) .register(meterRegistry) .increment(); } } // By implementing onEvent with `instanceof`, the `support` and `isAsync` // methods are no longer needed, as the base interface provides safe defaults. } ``` -------------------------------- ### Production (High-Throughput) Profile Configuration Source: https://github.com/alibaba/compileflow/blob/master/docs/en/configuration.md YAML configuration for a production environment designed to maximize processing power for CPU-intensive workflows. It increases thread counts, cache size, and enables observability features. ```yaml compileflow: # Use a higher thread count, e.g., 2x to 4x CPU cores, if flows are I/O bound. executor: compilation-threads: 4 execution-threads: 32 # Adjust based on CPU cores and load cache: runtime-max-size: 10000 # Large cache to avoid re-compilation observability: enabled: true metrics-enabled: true events-async: true # Use async events to avoid blocking execution threads ``` -------------------------------- ### Test Case 2: Discounted Price JSON Request Source: https://github.com/alibaba/compileflow/blob/master/docs/en/quick-start.md This JSON payload represents a group of 4 customers, which should trigger the discounted pricing logic in the KTV billing process. ```json ["customer1", "customer2", "customer3", "customer4"] ``` -------------------------------- ### ProcessSource Source: https://github.com/alibaba/compileflow/blob/master/docs/en/api-reference.md Defines the source of a process to be executed. All methods require a unique `code` to identify the process in the cache. ```APIDOC ## `ProcessSource` ### Description Defines the source of a process to be executed. All methods require a unique `code` to identify the process in the cache. ### Static Methods ```java // Load from the classpath (Recommended) // The engine will search the classpath for a process file matching the code. static ProcessSource fromCode(String code); // Load from a filesystem path static ProcessSource fromFile(String code, String filePath); static ProcessSource fromFile(String code, File file); // Load from a specific path within the classpath static ProcessSource fromClasspath(String code, String resourcePath); // Load from a URL static ProcessSource fromUrl(String code, String url); static ProcessSource fromUrl(String code, URL url); // Load directly from an XML string content static ProcessSource fromContent(String code, String xmlContent); ``` ``` -------------------------------- ### ScriptTask Node Protocol Source: https://github.com/alibaba/compileflow/wiki/协议详解 Defines a script task node that executes an expression. Supports 'QL' (Query Language) for expression evaluation. ```xml ``` -------------------------------- ### Test Case 2: Discounted Price JSON Response Source: https://github.com/alibaba/compileflow/blob/master/docs/en/quick-start.md This JSON response shows the calculated price for a group of 4 customers, reflecting the applied discount. ```json { "price": 100 } ``` -------------------------------- ### Primary CompileFlow Configuration in application.yml Source: https://github.com/alibaba/compileflow/blob/master/docs/en/configuration.md Configure CompileFlow's core settings like model type, thread pools for compilation and execution, and cache size. Enable observability for production environments. ```yaml compileflow: # [General] The process model type. TBBPM is optimized for enterprise workflows, # while BPMN follows international standards. # Options: TBBPM, BPMN model-type: TBBPM # [Performance] The two most critical performance settings. executor: # Number of threads for compiling flow definitions. # Recommended: 1-4. Default: Math.min(2, Math.max(1, CPUs/8)). Increase only if you have many flows to compile at startup. compilation-threads: 2 # Number of threads for executing flows. # Recommended: Start with the number of CPU cores and tune based on load. Default: Math.max(4, CPUs). execution-threads: 16 # [Cache] The most important cache setting. cache: # Maximum number of compiled flows to keep in memory. # Higher values improve performance but consume more memory. # Recommended: 100-500 (dev), 2000-10000 (prod). runtime-max-size: 2000 # [Observability] Settings for monitoring and metrics. observability: # Master switch to enable all monitoring features (metrics, events, tracing). # Essential for production environments. enabled: true ``` -------------------------------- ### Enable CompileFlow Observability in Spring Boot Source: https://github.com/alibaba/compileflow/blob/master/docs/en/monitoring.md Configure CompileFlow's observability features, including enabling the master switch and setting asynchronous event processing. This is required for any listeners to be triggered. ```yaml compileflow: observability: # Master switch to enable all monitoring features (metrics, events, tracing). # This must be true for any listeners to be triggered. enabled: true # For performance-critical applications, ensure events are processed asynchronously. events-async: true ``` -------------------------------- ### Java Code for CompileFlow Loop Process Source: https://github.com/alibaba/compileflow/wiki/协议详解 Translates the CompileFlow loop process protocol into executable Java code. This code iterates through a list and executes an action for each item. ```java int i = -1; for (String p : pList) { i++; //AutoTaskNode: 每人唱一首歌 ((MockSpringBean)BeanProvider.getBean("mockSpringBean")).sing((String)DataType.transfer(p, String.class)); } ``` -------------------------------- ### Implement Audit Logger Event Listener Source: https://github.com/alibaba/compileflow/blob/master/docs/en/extension-guide.md Implement the ProcessEventListener interface to react to engine lifecycle events like execution completion. Mark the class with @ExtensionRealization and configure it via SPI. Process events asynchronously for better performance. ```java package com.example.listeners; import com.alibaba.compileflow.engine.core.event.*; import com.alibaba.compileflow.engine.core.extension.ExtensionRealization; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ExtensionRealization // Marks this as a discoverable extension public class AuditLoggerListener implements ProcessEventListener { private static final Logger AUDIT_LOGGER = LoggerFactory.getLogger("audit"); @Override public void onEvent(ProcessEvent event) { if (event instanceof ProcessCoreEvents.ExecutionCompleted) { ProcessCoreEvents.ExecutionCompleted completedEvent = (ProcessCoreEvents.ExecutionCompleted) event; AUDIT_LOGGER.info("SUCCESS: Process [{}] finished in {}ms. TraceId: {}", completedEvent.getProcessCode(), completedEvent.getContext().getDurationMs(), completedEvent.getContext().getTraceId()); } } @Override public boolean support(ProcessEventExtensionContext context) { // Performance optimization: only receive the events you need. return context.getEvent().getEventType() == ProcessEvent.EventType.EXECUTION_COMPLETED; } @Override public boolean isAsync() { // Recommended: process events asynchronously to avoid blocking the engine. return true; } } ``` -------------------------------- ### Trigger Human Task Completion Source: https://github.com/alibaba/compileflow/blob/master/docs/en/node-support.md After implementing a human task with waitTask, this Java code demonstrates how to complete the task by triggering it with the approval result. ```java ProcessResult> result = engine.trigger( ProcessSource.fromCode("approval.flow"), "waitForApproval", // tag approvalData // approval result ); ```