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

feat: JVM docs for secrets / config and retry #2980

Merged
merged 1 commit into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 96 additions & 2 deletions docs/content/docs/reference/retries.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,91 @@ Some FTL features allow specifying a retry policy via a Go comment directive. Re

The directive has the following syntax:

{% code_selector() %}
<!-- go -->

```go
//ftl:retry [<attempts=10>] <min-backoff> [<max-backoff=1hr>] [catch <catchVerb>]
```

<!-- kotlin -->

```kotlin
@Retry(attempts = 10, minBackoff = "5s", maxBackoff = "1h", catchVerb = "<catchVerb>", catchModule = "<catchModule>")
```

<!-- java -->

```java
@Retry(attempts = 10, minBackoff = "5s", maxBackoff = "1h", catchVerb = "<catchVerb>", catchModule = "<catchModule>")
```

{% end %}

For example, the following function will retry up to 10 times, with a delay of 5s, 10s, 20s, 40s, 60s, 60s, etc.

{% code_selector() %}
<!-- go -->

```go
//ftl:retry 10 5s 1m
func Process(ctx context.Context, in Invoice) error {
// ...
}
```
<!-- kotlin -->

```kotlin
@Retry(count = 10, minBackoff = "5s", maxBackoff = "1m")
fun process(inv: Invoice) {
// ...
}
```
<!-- java -->

```java
@Retry(count = 10, minBackoff = "5s", maxBackoff = "1m")
public void process(Invoice in) {
// ...
}
```

{% end %}

### PubSub

Subscribers can have a retry policy. For example:

{% code_selector() %}
<!-- go -->

```go
//ftl:subscribe exampleSubscription
//ftl:retry 5 1s catch recoverPaymentProcessing
func ProcessPayment(ctx context.Context, payment Payment) error {
...
...
}
```
<!-- kotlin -->

```kotlin
@Subscription(topic = "example", module = "publisher", name = "exampleSubscription")
@Retry(count = 5, minBackoff = "1s", catchVerb = "recoverPaymentProcessing")
fun processPayment(payment: Payment) {
// ...
}
```
<!-- java -->

```java
@Subscription(topic = "example", module = "publisher", name = "exampleSubscription")
@Retry(count = 5, minBackoff = "1s", catchVerb = "recoverPaymentProcessing")
public void processPayment(Payment payment) {
// ...
}
```

{% end %}
### FSM

Retries can be declared on the FSM or on individual transition verbs. Retries declared on a verb take precedence over ones declared on the FSM. For example:
Expand Down Expand Up @@ -70,16 +131,49 @@ After all retries have failed, a catch verb can be used to safely recover.

These catch verbs have a request type of `builtin.CatchRequest<Req>` and no response type. If a catch verb returns an error, it will be retried until it succeeds so it is important to handle errors carefully.


{% code_selector() %}
<!-- go -->

```go
//ftl:retry 5 1s catch recoverPaymentProcessing
func ProcessPayment(ctx context.Context, payment Payment) error {
...
...
}

//ftl:verb
func RecoverPaymentProcessing(ctx context.Context, request builtin.CatchRequest[Payment]) error {
// safely handle final failure of the payment
}
```
<!-- kotlin -->

```kotlin

@Retry(count = 5, minBackoff = "1s", catchVerb = "recoverPaymentProcessing")
fun processPayment(payment: Payment) {
// ...
}

@Verb
fun recoverPaymentProcessing(req: CatchRequest<Payment>) {
// safely handle final failure of the payment
}
```
<!-- java -->

```java
@Retry(count = 5, minBackoff = "1s", catchVerb = "recoverPaymentProcessing")
public void processPayment(Payment payment) {
// ...
}

@Verb
public void recoverPaymentProcessing(CatchRequest<Payment> req) {
// safely handle final failure of the payment
}
```

{% end %}

For FSMs, after a catch verb has been successfully called the FSM will moved to the failed state.
59 changes: 59 additions & 0 deletions docs/content/docs/reference/secretsconfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ top = false

Configuration values are named, typed values. They are managed by the `ftl config` command-line.

{% code_selector() %}

<!-- go -->


To declare a configuration value use the following syntax:

```go
Expand All @@ -29,10 +34,39 @@ Then to retrieve a configuration value:
username = defaultUser.Get(ctx)
```

<!-- kotlin -->

Configuration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:

```kotlin
@Export
@Verb
fun hello(helloRequest: HelloRequest, @Config("defaultUser") defaultUser: String): HelloResponse {
return HelloResponse("Hello, $defaultUser")
}
```
<!-- java -->
Configuration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:

```java
@Export
@Verb
HelloResponse hello(HelloRequest helloRequest, @Config("defaultUser") String defaultUser) {
return new HelloResponse("Hello, " + defaultUser);
}
```

{% end %}


### Secrets

Secrets are encrypted, named, typed values. They are managed by the `ftl secret` command-line.

{% code_selector() %}

<!-- go -->

Declare a secret with the following:

```go
Expand All @@ -45,6 +79,29 @@ Then to retrieve a secret value:
key = apiKey.Get(ctx)
```

<!-- kotlin -->

Configuration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:

```kotlin
@Export
@Verb
fun hello(helloRequest: HelloRequest, @Secret("apiKey") apiKey: String): HelloResponse {
return HelloResponse("Hello, ${api.call(apiKey)}")
}
```
<!-- java -->
Configuration values can be injected into FTL methods, such as `@Verb`, HTTP ingress, Cron etc. To inject a configuration value, use the following syntax:

```java
@Export
@Verb
HelloResponse hello(HelloRequest helloRequest, @Secret("apiKey") String apiKey) {
return new HelloResponse("Hello, " + api.call(apiKey));
}
```

{% end %}
### Transforming secrets/configuration

Often, raw secret/configuration values aren't directly useful. For example, raw credentials might be used to create an API client. For those situations `ftl.Map()` can be used to transform a configuration or secret value into another type:
Expand All @@ -55,3 +112,5 @@ var client = ftl.Map(ftl.Secret[Credentials]("credentials"),
return api.NewClient(creds)
})
```

This is not currently supported in Kotlin or Java.
2 changes: 1 addition & 1 deletion internal/lsp/hoveritems.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading