Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial implementation of synchronous Waiters #571

Merged
merged 14 commits into from
Feb 3, 2025

Conversation

hpmellema
Copy link
Contributor

@hpmellema hpmellema commented Jan 31, 2025

Description of changes

Adds an initial implementation of synchronous smithy waiters.

Waiters can be created without codegen, but a codegen integration is provided to automatically create waiters base on trait in the service model.

Base usage

Example of creating and using a waiter in code:

var waiter = Waiter.builder(client::getFoosSync)
                .failure(Matcher.output(o -> o.status().equals("DONE"))))
                .build();
// Wait for up to 2 seconds for waiter to complete
waiter.wait(input, Duration.ofSeconds(2));

If the waiter ends in a FAILURE state it throws a WaiterFailureException.

Codegen

Waiters can be code generated into a container class using the waiter codegen integration. This integration needs to be added on the smithyBuild configuration of the package and the waiters package needs to be added as a runtime dependency for the generated waiter code to work. For example:

// build.gradle.kts
dependencies {
     smithyBuild(project(":codegen:integrations:waiters-codegen"))
     implementation(project(":waiters"))
     ...
}

The codegen integration will create a waiter container that provides pre-defined waiters based on smithy traits in the model.
For example, the following smithy model:

@waitable(
    OrderExists: {
        documentation: "Wait until the order exists"
        acceptors: [
            {
                state: "success"
                matcher: { success: true }
            }
            {
                state: "success"
                matcher: { errorType: OtherError }
            }
            {
                state: "retry"
                matcher: { errorType: OrderNotFound }
            }
        ]
    }
)
@readonly
@http(method: "GET", uri: "/order/{id}")
operation GetOrder {
    input := for Order {
        @httpLabel
        @required
        $id
    }

    output := for Order {
        @required
        $id

        @required
        $coffeeType

        @required
        $status
    }

    errors: [
        OrderNotFound
        OtherError
    ]
}

Will generate:

/**
 * Waiters for the {@link CoffeeShopClient} client.
 */
public record CoffeeShopWaiter(CoffeeShopClient client) {
    public CoffeeShopWaiter {
        Objects.requireNonNull(client, "client cannot be null");
    }

    /**
     * Wait until the order exists
     */
    public Waiter<GetOrderInput, GetOrderOutput> OrderExists() {
        return Waiter.<GetOrderInput, GetOrderOutput>builder(client::getOrder)
            .backoffStrategy(BackoffStrategy.getDefault(120000L, 2000L))
            .success(Matcher.success(true))
            .success(Matcher.errorType("com.example#OtherError"))
            .retry(Matcher.errorType("com.example#OrderNotFound"))
            .build();
    }
    
    // Any other waiters....

}

The codegen integration will also create a waiter() method on clients that instantiates a new instance of the waiter container for the current client.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@hpmellema hpmellema requested a review from adwsingh February 3, 2025 18:21
@hpmellema hpmellema enabled auto-merge (squash) February 3, 2025 22:01
@hpmellema hpmellema merged commit ce216dc into smithy-lang:main Feb 3, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants