Skip to content
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
44 changes: 21 additions & 23 deletions docs/explanations/migrating-from-temporal.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ Learn more in the [workflows tutorial](../golang/tutorials/workflow-tutorial.md)
```java
@Workflow(name = "orderWorkflow")
public String orderWorkflow(Order order) {
String result = DBOS.runStep(() -> validateOrder(order), "validateOrder");
String confirmation = DBOS.runStep(() -> processPayment(result), "processPayment");
String result = dbos.runStep(() -> validateOrder(order), "validateOrder");
String confirmation = dbos.runStep(() -> processPayment(result), "processPayment");
return confirmation;
}
```
Expand Down Expand Up @@ -189,7 +189,7 @@ Learn more in the [workflows tutorial](../golang/tutorials/workflow-tutorial.md)

```java
// Starting a workflow from in your application
WorkflowHandle<String, Exception> handle = DBOS.startWorkflow(
WorkflowHandle<String, Exception> handle = dbos.startWorkflow(
() -> proxy.orderWorkflow(order),
new StartWorkflowOptions().withWorkflowId("order-123")
);
Expand All @@ -199,7 +199,7 @@ String result = handle.getResult();
```java
// Starting a workflow from another application using the DBOS Client
var client = new DBOSClient(dbUrl, dbUser, dbPassword);
var options = new DBOSClient.EnqueueOptions("OrderImpl", "orderWorkflow", "orders");
var options = new EnqueueOptions("orderWorkflow", "com.example.OrderImpl", QueueName.of("orders"));
var handle = client.enqueueWorkflow(options, new Object[]{order});
Object result = handle.getResult();
```
Expand Down Expand Up @@ -249,7 +249,7 @@ Learn more in the [workflows tutorial](../golang/tutorials/workflow-tutorial.md#
<TabItem value="java" label="Java">

```java
DBOS.startWorkflow(
dbos.startWorkflow(
() -> proxy.orderWorkflow(order),
new StartWorkflowOptions().withWorkflowId("payment-idempotency-key")
);
Expand Down Expand Up @@ -306,7 +306,7 @@ Learn more in the [workflows tutorial](../golang/tutorials/workflow-tutorial.md#
<TabItem value="java" label="Java">

```java
DBOS.sleep(Duration.ofHours(24));
dbos.sleep(Duration.ofHours(24));
```

Learn more in the [workflows tutorial](../java/tutorials/workflow-tutorial.md#durable-sleep).
Expand Down Expand Up @@ -386,8 +386,8 @@ Learn more in the [steps tutorial](../golang/tutorials/step-tutorial.md).
<TabItem value="java" label="Java">

```java
// Steps are called inline using DBOS.runStep
boolean result = DBOS.runStep(() -> sendEmail(to, body), "sendEmail");
// Steps are called inline using dbos.runStep
boolean result = dbos.runStep(() -> sendEmail(to, body), "sendEmail");
```

Learn more in the [steps tutorial](../java/tutorials/step-tutorial.md).
Expand Down Expand Up @@ -465,12 +465,11 @@ Learn more in the [steps tutorial](../golang/tutorials/step-tutorial.md#configur
<TabItem value="java" label="Java">

```java
boolean result = DBOS.runStep(
boolean result = dbos.runStep(
() -> sendEmail(to, body),
new StepOptions("sendEmail")
.withRetriesAllowed(true)
.withMaxAttempts(5)
.withIntervalSeconds(1.0)
.withRetryInterval(Duration.ofSeconds(1))
.withBackoffRate(2.0)
);
```
Expand Down Expand Up @@ -637,16 +636,16 @@ Learn more in the [workflow communication tutorial](../golang/tutorials/workflow
@Workflow(name = "orderWorkflow")
public void orderWorkflow(Order order) {
// ... start order processing ...
String paymentStatus = (String) DBOS.recv("payment_status", Duration.ofHours(1));
if (paymentStatus != null && paymentStatus.equals("paid")) {
Optional<String> paymentStatus = dbos.recv("payment_status", Duration.ofHours(1));
if (paymentStatus.map("paid"::equals).orElse(false)) {
// handle success
} else {
// handle failure
}
}

// Sending the message
DBOS.send("order-123", "paid", "payment_status");
dbos.send("order-123", "paid", "payment_status");
```

Learn more in the [workflow communication tutorial](../java/tutorials/workflow-communication.md#workflow-messaging-and-notifications).
Expand Down Expand Up @@ -745,14 +744,14 @@ Learn more in the [workflow communication tutorial](../golang/tutorials/workflow
```java
@Workflow(name = "orderWorkflow")
public void orderWorkflow(Order order) {
DBOS.setEvent("progress", 25);
dbos.setEvent("progress", 25);
// ... validate order ...
DBOS.setEvent("progress", 50);
dbos.setEvent("progress", 50);
// ...
}

// Reading workflow state
int progress = (int) DBOS.getEvent("order-123", "progress", Duration.ofSeconds(30));
Optional<Integer> progress = dbos.getEvent("order-123", "progress", Duration.ofSeconds(30));
```

Learn more in the [workflow communication tutorial](../java/tutorials/workflow-communication.md#workflow-events).
Expand Down Expand Up @@ -831,14 +830,13 @@ Learn more in the [queues tutorial](../golang/tutorials/queue-tutorial.md).
<TabItem value="java" label="Java">

```java
// Define a queue with concurrency limits
Queue orderQueue = new Queue("order-processing").withConcurrency(10);
DBOS.registerQueue(orderQueue);
// Register a queue with concurrency limits (after dbos.launch())
dbos.registerQueue("order-processing", QueueOptions.setConcurrency(10));

// Enqueue a workflow
WorkflowHandle<String, Exception> handle = DBOS.startWorkflow(
WorkflowHandle<String, Exception> handle = dbos.startWorkflow(
() -> proxy.orderWorkflow(order),
new StartWorkflowOptions().withQueue(orderQueue)
new StartWorkflowOptions().withQueue("order-processing")
);
String result = handle.getResult();
```
Expand Down Expand Up @@ -986,7 +984,7 @@ public String parentWorkflow() {
String result = proxy.childWorkflow(data);

// Or start in background
WorkflowHandle<String, Exception> handle = DBOS.startWorkflow(
WorkflowHandle<String, Exception> handle = dbos.startWorkflow(
() -> proxy.childWorkflow(data),
new StartWorkflowOptions()
);
Expand Down
19 changes: 11 additions & 8 deletions docs/explanations/portable-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,17 @@ const handle = await client.enqueue(
<TabItem value="java" label="Java">

```java
import dev.dbos.transact.client.DBOSClient;
import dev.dbos.transact.client.EnqueueOptions;
import dev.dbos.transact.DBOSClient;
import dev.dbos.transact.EnqueueOptions;
import dev.dbos.transact.workflow.QueueName;
import dev.dbos.transact.workflow.SerializationStrategy;

DBOSClient client = new DBOSClient(dbUrl, dbUser, dbPassword);
var options = new EnqueueOptions("OrderProcessor", "processOrder", "orders")
var client = new DBOSClient(dbUrl, dbUser, dbPassword);
var options = new EnqueueOptions("process_order", QueueName.of("orders"))
// The name of the application that implements process_order
.withApplicationName("order-service")
.withSerialization(SerializationStrategy.PORTABLE);
var handle = client.enqueue(options, "order-123");
var handle = client.enqueueWorkflow(options, new Object[] {"order-123"});
```

</TabItem>
Expand Down Expand Up @@ -250,7 +253,7 @@ However, individual operations can override this&mdash;for example, a workflow r
Each language's `setEvent` and `writeStream` methods accept a serialization parameter for this purpose.

`send` is a special case, because messages target a different workflow and the sender does not know what serialization that workflow expects.
In Python, TypeScript, and Go, a `send` from inside a workflow defaults to that workflow's serialization format, but in Java it always uses the default serializer.
In every language, a `send` from inside a workflow defaults to that workflow's serialization format.
You should therefore always set the serialization format explicitly on `send` when communicating cross-language.

You can also send a message to a workflow using the PL/pgSQL function [`dbos.send_message`](system-tables.md#dbossend_message).
Expand Down Expand Up @@ -355,7 +358,7 @@ import dev.dbos.transact.DBOS;
import dev.dbos.transact.workflow.SerializationStrategy;

// Send a message readable by any language
DBOS.send(
dbos.send(
"workflow-123",
Map.of("status", "complete", "count", 42),
"updates",
Expand All @@ -364,7 +367,7 @@ DBOS.send(
);

// Set an event readable by any language
DBOS.setEvent(
dbos.setEvent(
"progress",
Map.of("percent", 75),
SerializationStrategy.PORTABLE
Expand Down
14 changes: 13 additions & 1 deletion docs/explanations/sharing-a-system-database.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,25 @@ if err != nil {
result, err := handle.GetResult()
```

</TabItem>
<TabItem value="java" label="Java">

```java
var options = new EnqueueOptions("process_order", QueueName.of("orders"))
// The name of the application that implements process_order
.withApplicationName("order-service");
WorkflowHandle<Object, Exception> handle =
dbos.enqueueWorkflow(options, new Object[] {"order-123"});
Object result = handle.getResult();
```

</TabItem>
</Tabs>

If the applications are written in different languages, also set the serialization type to portable so the target application can read the arguments.
See [Cross-Language Interaction](./portable-workflows.md) for details.

You can do the same from a [DBOS Client](../python/reference/client.md), which additionally supports registering queues, creating schedules, and debouncing workflows on behalf of a named application.
You can do the same from a DBOS Client ([Python](../python/reference/client.md), [Java](../java/reference/client.md)), which additionally supports registering queues, creating schedules, and debouncing workflows on behalf of a named application.
Always set the client's application name if multiple applications share a system database.

## Unowned Rows
Expand Down
2 changes: 1 addition & 1 deletion docs/java/examples/widget-store.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ The endpoint accepts an [idempotency key](../tutorials/workflow-tutorial.md#work
public ResponseEntity<String> checkout(@PathVariable String key) {
logger.info("Checkout requested with key: " + key);

var options = new StartWorkflowOptions(key);
var options = new StartWorkflowOptions().withWorkflowId(key);
dbos.startWorkflow(() -> service.checkoutWorkflow(), options);
var paymentId = dbos.<String>getEvent(key, PAYMENT_ID, Duration.ofSeconds(60));
if (paymentId.isEmpty()) {
Expand Down
13 changes: 8 additions & 5 deletions docs/java/integrating-dbos.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Add DBOS to your application by including it in your build configuration.
<TabItem value="gradle" label="Gradle">
```groovy
dependencies {
implementation 'dev.dbos:transact:0.8.0'
implementation 'dev.dbos:transact:1.1.0'
}
```
</TabItem>
Expand All @@ -23,7 +23,7 @@ dependencies {
<dependency>
<groupId>dev.dbos</groupId>
<artifactId>transact</artifactId>
<version>0.8.0</version>
<version>1.1.0</version>
</dependency>
</dependencies>
```
Expand All @@ -44,12 +44,14 @@ public class MyApp {
// Configure DBOS
DBOSConfig dbosConfig = DBOSConfig.defaultsFromEnv("dbos-java-starter")
.withAppVersion("0.1.0");
DBOS dbos = new DBOS(config);
DBOS dbos = new DBOS(dbosConfig);

// Register your workflows and queues (see step 4)
// Register your workflows (see step 4)

// Launch DBOS
dbos.launch();

// Register your queues, which are stored in the system database
}
}
```
Expand Down Expand Up @@ -129,8 +131,9 @@ dbos.launch();
proxy.workflow();
```

**Important:** You must create all workflow proxies and queues before calling `dbos.launch()`.
**Important:** You must create all workflow proxies before calling `dbos.launch()`.
Workflow recovery begins after `dbos.launch()`, so all workflows must be registered before this point.
Queues are the opposite: their configuration is stored in the system database, so register them with [`dbos.registerQueue`](./reference/queues.md#dbosregisterqueue) after `dbos.launch()`.

You can add DBOS to your application incrementally—it won't interfere with code that's already there.
It's totally okay for your application to have one DBOS workflow alongside thousands of lines of non-DBOS code.
Expand Down
16 changes: 9 additions & 7 deletions docs/java/programming-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Then, install DBOS (plus Logback for logging) by adding the following to your `a

```kotlin
dependencies {
implementation("dev.dbos:transact:0.9.0")
implementation("dev.dbos:transact:1.1.0")
implementation("org.slf4j:slf4j-simple:2.0.17") // needed to see DBOS log messages
implementation("io.javalin:javalin:7.0.1") // needed for creating HTTP endpoint later in the guide

Expand Down Expand Up @@ -120,7 +120,7 @@ Now, build and run this code with:
Your program should print output like:

```shell
[main] INFO dev.dbos.transact.DBOS - Launching DBOS v0.9.0
[main] INFO dev.dbos.transact.DBOS - Launching DBOS v1.1.0
[main] INFO dev.dbos.transact.execution.DBOSExecutor - DBOS Executor starting
[main] INFO dev.dbos.transact.execution.DBOSExecutor - System Database: jdbc:postgresql://localhost:5432/dbos_java_starter
[main] INFO dev.dbos.transact.execution.DBOSExecutor - System Database User name: postgres
Expand Down Expand Up @@ -245,7 +245,7 @@ package org.example;
import dev.dbos.transact.DBOS;
import dev.dbos.transact.StartWorkflowOptions;
import dev.dbos.transact.config.DBOSConfig;
import dev.dbos.transact.workflow.Queue;
import dev.dbos.transact.workflow.QueueOptions;
import dev.dbos.transact.workflow.Workflow;
import dev.dbos.transact.workflow.WorkflowHandle;

Expand Down Expand Up @@ -308,11 +308,12 @@ public class App {
Example proxy = dbos.registerProxy(Example.class, impl);
impl.setSelf(proxy);

var queue = new Queue("example-queue");
dbos.registerQueue(queue);

Javalin.create(config -> {
config.events.serverStarting(dbos::launch);
config.events.serverStarting(() -> {
dbos.launch();
// Queues are stored in the system database, so register them after launch
dbos.registerQueue("example-queue", QueueOptions.empty());
});
config.events.serverStopping(dbos::shutdown);
config.routes.get("/", ctx -> {
proxy.queueWorkflow();
Expand All @@ -323,6 +324,7 @@ public class App {
}
```

The queue is registered with [`dbos.registerQueue`](./reference/queues.md#dbosregisterqueue) after `dbos.launch()`, because queue configuration is stored in the system database.
When you enqueue a function by passing `new StartWorkflowOptions().withQueue("example-queue")` into `dbos.startWorkflow`, DBOS executes it _asynchronously_, running it in the background without waiting for it to finish.
`dbos.startWorkflow` returns a handle representing the state of the enqueued function.
This example enqueues ten functions, then waits for them all to finish using `.getResult()` to wait for each of their handles.
Expand Down
Loading
Loading