# How to Configure Execution Timoutouts for Extensions Using firstExtension() in cp-ddd-framework

> Configure extension execution timeouts in cp-ddd-framework using firstExtension(). Set millisecond values to enforce limits and prevent breaches with ExtTimeoutException for robust extension management.

- Repository: [Funky Gao/cp-ddd-framework](https://github.com/funkygao/cp-ddd-framework)
- Tags: how-to-guide
- Published: 2026-03-02

---

**To configure execution timeouts for extensions in the cp-ddd-framework, invoke the three-argument `firstExtension(Class<Ext>, IIdentity, int)` overload with a positive millisecond value, which propagates the timeout to `ExtensionInvocationHandler` and enforces limits via `Future.get()` with `ExtTimeoutException` on breach.**

The cp-ddd-framework provides a robust extension-point mechanism for domain-driven design applications, allowing developers to configure execution timeouts for extensions to prevent long-running operations from blocking critical business flows. The `firstExtension()` method in `io.github.dddplus.runtime.DDD` provides overloads that control timeout behavior through the underlying proxy invocation handler.

## Understanding the firstExtension() Timeout API

The `DDD` class exposes multiple pathways for retrieving extension instances. The commonly used two-argument overload automatically disables timeout protection by passing a zero value:

```java
public static <Ext extends IDomainExtension> Ext firstExtension(@NonNull Class<Ext> extClazz,
                                                              @NonNull IIdentity identity) {
    return firstExtension(extClazz, identity, 0);
}

```

As implemented in [`dddplus-runtime/src/main/java/io/github/dddplus/runtime/DDD.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/dddplus-runtime/src/main/java/io/github/dddplus/runtime/DDD.java) (lines 67-71), this method delegates to the three-argument variant while passing **0 milliseconds**, meaning no timeout enforcement occurs.

To configure execution timeouts for extensions, call the overload that accepts a `timeoutInMs` parameter:

```java
ExtensionInvocationHandler<Ext, R> proxy =
        new ExtensionInvocationHandler<>(extClazz, identity, null, null,
                                        InternalIndexer.registeredInterceptor(),
                                        timeoutInMs);
return proxy.createProxy();

```

This construction appears at lines 89-91 in [`DDD.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/DDD.java), where the `timeoutInMs` value propagates directly into the `ExtensionInvocationHandler` constructor.

## How Timeout Enforcement Works

The `ExtensionInvocationHandler` class located at [`dddplus-runtime/src/main/java/io/github/dddplus/runtime/ExtensionInvocationHandler.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/dddplus-runtime/src/main/java/io/github/dddplus/runtime/ExtensionInvocationHandler.java) manages timeout logic during method invocation through the following execution path:

- **Validation** (lines 38-40): The handler checks if `timeoutInMs > 0` to determine whether timeout protection is active.
- **Delegation** (lines 48-50): When enabled, the invocation routes to `invokeExtensionMethodWithTimeout()`.
- **Execution** (lines 65-70): The framework executes the extension method within a `Future` and calls `Future.get(timeout, TimeUnit.MILLISECONDS)`.
- **Exception Translation**: When the timeout expires, the handler catches `TimeoutException` and wraps it as `ExtTimeoutException` (defined in [`dddplus-runtime/src/main/java/io/github/dddplus/runtime/ExtTimeoutException.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/dddplus-runtime/src/main/java/io/github/dddplus/runtime/ExtTimeoutException.java), lines 11-14).

## Practical Implementation Examples

When you configure execution timeouts for extensions in production environments, always specify the timeout explicitly to prevent indefinite blocking:

```java
import io.github.dddplus.runtime.DDD;
import io.github.dddplus.ext.IDomainExtension;
import io.github.dddplus.ext.IIdentity;

public class OrderIdentity implements IIdentity {
    private final String orderNo;
    
    public OrderIdentity(String orderNo) { 
        this.orderNo = orderNo; 
    }
    
    public String getOrderNo() { return orderNo; }
}

public class ExtensionClient {
    public void processWithTimeout() {
        IIdentity identity = new OrderIdentity("ORD12345");
        
        // Configure 3000ms timeout for this extension execution
        MyExtension ext = DDD.firstExtension(MyExtension.class, identity, 3000);
        
        try {
            ext.process();
        } catch (ExtTimeoutException e) {
            // Handle timeout - extension exceeded 3 seconds
            logger.error("Extension execution timed out", e);
        }
    }
}

```

For extension points requiring consistent timeout policies across your application, create a utility wrapper that encapsulates the timeout value:

```java
public class ExtensionHelper {
    private static final int DEFAULT_TIMEOUT_MS = 5000;
    
    public static <T extends IDomainExtension> T getExtensionWithTimeout(
            Class<T> clazz, IIdentity identity) {
        return DDD.firstExtension(clazz, identity, DEFAULT_TIMEOUT_MS);
    }
}

```

## Summary

- The two-argument `firstExtension(Class, IIdentity)` overload disables timeouts by passing **0 milliseconds** to the handler.
- To configure execution timeouts for extensions, use the three-argument overload with a positive millisecond value.
- The `ExtensionInvocationHandler` enforces timeouts using `Future.get()` and converts `TimeoutException` to `ExtTimeoutException`.
- Key source files: [`DDD.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/DDD.java) (lines 67-71, 89-91), [`ExtensionInvocationHandler.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/ExtensionInvocationHandler.java) (lines 38-50, 65-70), and [`ExtTimeoutException.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/ExtTimeoutException.java) (lines 11-14).

## Frequently Asked Questions

### What happens when I pass 0 as the timeout value to firstExtension()?

Passing **0** milliseconds disables timeout protection entirely, allowing the extension to run indefinitely until completion or failure. The `ExtensionInvocationHandler` bypasses the `Future.get(timeout, TimeUnit.MILLISECONDS)` call and executes the extension method directly without time constraints, as implemented in the validation logic at lines 38-40 of [`ExtensionInvocationHandler.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/ExtensionInvocationHandler.java).

### How does cp-ddd-framework handle timeout exceptions?

When an extension exceeds the specified timeout duration, the framework throws `ExtTimeoutException` (defined in [`ExtTimeoutException.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/ExtTimeoutException.java), lines 11-14). This exception wraps the underlying `java.util.concurrent.TimeoutException` and provides context about which extension point and identity triggered the timeout, enabling precise error handling in your domain logic at the call site.

### Can I set a global default timeout for all extension calls?

The framework does not provide a global configuration property for extension timeouts. You must explicitly pass the timeout value in each `firstExtension()` call or create a wrapper utility class that encapsulates your standard timeout values, ensuring consistent protection across your application without modifying the core framework classes in `dddplus-runtime`.

### Is the timeout enforced per-method call or per-extension instance?

The timeout is enforced **per-method invocation**. Each time you call a method on the proxy returned by `firstExtension()`, the `ExtensionInvocationHandler` creates a new execution context with the configured timeout. This means different method calls on the same extension instance can have different effective timeouts if you obtain new proxy instances with different timeout configurations.