Skip to content

Commit 9aad7b2

Browse files
authored
Update readme (dbos-inc#141)
1 parent 120b143 commit 9aad7b2

File tree

1 file changed

+91
-62
lines changed

1 file changed

+91
-62
lines changed

README.md

Lines changed: 91 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/dbos-inc/dbos-transact-golang?sort=semver)](https://github.com/dbos-inc/dbos-transact-golang/releases)
66
[![Join Discord](https://img.shields.io/badge/Discord-Join%20Chat-5865F2?logo=discord&logoColor=white)](https://discord.com/invite/jsmC6pXGgX)
77
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8+
[![GitHub Stars](https://img.shields.io/github/stars/dbos-inc/dbos-transact-golang?style=social)](https://github.com/dbos-inc/dbos-transact-golang)
89

910

1011
# DBOS Transact: Lightweight Durable Workflow Orchestration with Postgres
@@ -41,64 +42,62 @@ You add durable workflows to your existing Golang program by registering ordinar
4142
package main
4243

4344
import (
44-
"context"
45-
"fmt"
46-
"os"
45+
"context"
46+
"fmt"
47+
"os"
48+
"time"
4749

48-
"github.com/dbos-inc/dbos-transact-golang/dbos"
50+
"github.com/dbos-inc/dbos-transact-golang/dbos"
4951
)
5052

5153
func workflow(dbosCtx dbos.DBOSContext, _ string) (string, error) {
52-
_, err := dbos.RunAsStep(dbosCtx, func(ctx context.Context) (string, error) {
53-
return stepOne(ctx)
54-
})
55-
if err != nil {
56-
return "", err
57-
}
58-
return dbos.RunAsStep(dbosCtx, func(ctx context.Context) (string, error) {
59-
return stepTwo(ctx)
60-
})
54+
_, err := dbos.RunAsStep(dbosCtx, stepOne)
55+
if err != nil {
56+
return "", err
57+
}
58+
return dbos.RunAsStep(dbosCtx, stepTwo)
6159
}
6260

6361
func stepOne(ctx context.Context) (string, error) {
64-
fmt.Println("Step one completed!")
65-
return "Step 1 completed", nil
62+
fmt.Println("Step one completed!")
63+
return "Step 1 completed", nil
6664
}
6765

6866
func stepTwo(ctx context.Context) (string, error) {
69-
fmt.Println("Step two completed!")
70-
return "Step 2 completed - Workflow finished successfully", nil
67+
fmt.Println("Step two completed!")
68+
return "Step 2 completed - Workflow finished successfully", nil
7169
}
70+
7271
func main() {
7372
// Initialize a DBOS context
74-
ctx, err := dbos.NewDBOSContext(context.Background(), dbos.Config{
75-
DatabaseURL: os.Getenv("DBOS_SYSTEM_DATABASE_URL"),
76-
AppName: "myapp",
77-
})
78-
if err != nil {
79-
panic(err)
80-
}
73+
ctx, err := dbos.NewDBOSContext(context.Background(), dbos.Config{
74+
DatabaseURL: os.Getenv("DBOS_SYSTEM_DATABASE_URL"),
75+
AppName: "myapp",
76+
})
77+
if err != nil {
78+
panic(err)
79+
}
8180

8281
// Register a workflow
83-
dbos.RegisterWorkflow(ctx, workflow)
82+
dbos.RegisterWorkflow(ctx, workflow)
8483

8584
// Launch DBOS
86-
err = ctx.Launch()
87-
if err != nil {
88-
panic(err)
89-
}
90-
defer ctx.Cancel()
85+
err = ctx.Launch()
86+
if err != nil {
87+
panic(err)
88+
}
89+
defer ctx.Shutdown(2 * time.Second)
9190

9291
// Run a durable workflow and get its result
93-
handle, err := dbos.RunWorkflow(ctx, workflow, "")
94-
if err != nil {
95-
panic(err)
96-
}
97-
res, err := handle.GetResult()
98-
if err != nil {
99-
panic(err)
100-
}
101-
fmt.Println("Workflow result:", res)
92+
handle, err := dbos.RunWorkflow(ctx, workflow, "")
93+
if err != nil {
94+
panic(err)
95+
}
96+
res, err := handle.GetResult()
97+
if err != nil {
98+
panic(err)
99+
}
100+
fmt.Println("Workflow result:", res)
102101
}
103102
```
104103

@@ -129,6 +128,7 @@ They don't require a separate queueing service or message broker—just Post
129128
package main
130129

131130
import (
131+
"context"
132132
"fmt"
133133
"os"
134134
"time"
@@ -137,7 +137,7 @@ import (
137137
)
138138

139139
func task(ctx dbos.DBOSContext, i int) (int, error) {
140-
ctx.Sleep(5 * time.Second)
140+
dbos.Sleep(ctx, 5*time.Second)
141141
fmt.Printf("Task %d completed\n", i)
142142
return i, nil
143143
}
@@ -161,7 +161,7 @@ func main() {
161161
if err != nil {
162162
panic(err)
163163
}
164-
defer ctx.Cancel()
164+
defer ctx.Shutdown(2 * time.Second)
165165

166166
// Enqueue tasks and gather results
167167
fmt.Println("Enqueuing workflows")
@@ -217,7 +217,7 @@ It stores its wakeup time in Postgres so the workflow sleeps through any interru
217217

218218
```golang
219219
func workflow(ctx dbos.DBOSContext, duration time.Duration) (string, error) {
220-
ctx.Sleep(duration)
220+
dbos.Sleep(ctx, duration)
221221
return fmt.Sprintf("Workflow slept for %s", duration), nil
222222
}
223223

@@ -260,38 +260,67 @@ recvResult, err := recvHandle.GetResult()
260260

261261
</details>
262262

263+
## Getting Started
263264

264-
## DBOS workflows
265+
To get started, follow the [quickstart](https://docs.dbos.dev/quickstart) to install this open-source library and connect it to a Postgres database.
266+
Then, check out the [programming guide](https://docs.dbos.dev/python/programming-guide) to learn how to build with durable workflows and queues.
265267

266-
A workflow can be any function with the following signature:
267-
```golang
268-
type GenericWorkflowFunc[P any, R any] func(ctx context.Context, input P) (R, error)
269-
```
268+
## Documentation
270269

271-
To register a workflow call `dbos.RegisterWorkflow(dbosCtx, workflow)` after having initialized a DBOS Context. Workflows can only be registered before DBOS is launched.
270+
[https://docs.dbos.dev](https://docs.dbos.dev)
272271

272+
## Examples
273273

274-
Workflows can run steps, which can be any function with the following signature:
275-
```golang
276-
type GenericStepFunc[R any] func(ctx context.Context) (R, error)
277-
```
274+
[https://docs.dbos.dev/examples](https://docs.dbos.dev/examples)
278275

279-
To run a step within a workflow, use `RunAsStep`. Importantly, you must pass to `RunAsStep` the context received in the workflow function (see examples above.)
276+
## DBOS vs. Other Systems
280277

281-
The input and output of workflows and steps are memoized in your Postgres database for workflow recovery. Under the hood, DBOS uses the [encoding/gob](https://pkg.go.dev/encoding/gob) package for serialization (this means that only exported fields will be memoized and types without exported fields will generate an error.)
278+
<details><summary><strong>DBOS vs. Temporal</strong></summary>
282279

283-
## Getting started
280+
####
284281

285-
Install the DBOS Transact package in your program:
282+
Both DBOS and Temporal provide durable execution, but DBOS is implemented in a lightweight Postgres-backed library whereas Temporal is implemented in an externally orchestrated server.
286283

287-
```shell
288-
go get github.com/dbos-inc/dbos-transact-golang
289-
```
284+
You can add DBOS to your program by installing this open-source library, connecting it to Postgres, and annotating workflows and steps.
285+
By contrast, to add Temporal to your program, you must rearchitect your program to move your workflows and steps (activities) to a Temporal worker, configure a Temporal server to orchestrate those workflows, and access your workflows only through a Temporal client.
286+
[This blog post](https://www.dbos.dev/blog/durable-execution-coding-comparison) makes the comparison in more detail.
290287

291-
You can store and export a Postgres connection string in the `DBOS_SYSTEM_DATABASE_URL` environment variable for DBOS to manage your workflows state. By default, DBOS will use `postgres://postgres:${PGPASSWORD}@localhost:5432/dbos?sslmode=disable`.
288+
**When to use DBOS:** You need to add durable workflows to your applications with minimal rearchitecting, or you are using Postgres.
292289

290+
**When to use Temporal:** You don't want to add Postgres to your stack, or you need a language DBOS doesn't support yet.
293291

294-
## ⭐️ Like this project?
292+
</details>
293+
294+
<details><summary><strong>DBOS vs. Airflow</strong></summary>
295+
296+
####
297+
298+
DBOS and Airflow both provide workflow abstractions.
299+
Airflow is targeted at data science use cases, providing many out-of-the-box connectors but requiring workflows be written as explicit DAGs and externally orchestrating them from an Airflow cluster.
300+
Airflow is designed for batch operations and does not provide good performance for streaming or real-time use cases.
301+
DBOS is general-purpose, but is often used for data pipelines, allowing developers to write workflows as code and requiring no infrastructure except Postgres.
302+
303+
**When to use DBOS:** You need the flexibility of writing workflows as code, or you need higher performance than Airflow is capable of (particularly for streaming or real-time use cases).
295304

305+
**When to use Airflow:** You need Airflow's ecosystem of connectors.
306+
307+
</details>
308+
309+
<details><summary><strong>DBOS vs. Celery/BullMQ</strong></summary>
310+
311+
####
312+
313+
DBOS provides a similar queue abstraction to dedicated queueing systems like Celery or BullMQ: you can declare queues, submit tasks to them, and control their flow with concurrency limits, rate limits, timeouts, prioritization, etc.
314+
However, DBOS queues are **durable and Postgres-backed** and integrate with durable workflows.
315+
For example, in DBOS you can write a durable workflow that enqueues a thousand tasks and waits for their results.
316+
DBOS checkpoints the workflow and each of its tasks in Postgres, guaranteeing that even if failures or interruptions occur, the tasks will complete and the workflow will collect their results.
317+
By contrast, Celery/BullMQ are Redis-backed and don't provide workflows, so they provide fewer guarantees but better performance.
318+
319+
**When to use DBOS:** You need the reliability of enqueueing tasks from durable workflows.
320+
321+
**When to use Celery/BullMQ**: You don't need durability, or you need very high throughput beyond what your Postgres server can support.
322+
</details>
323+
324+
## ⭐️ Like this project?
296325
[Star it on GitHub](https://github.com/dbos-inc/dbos-transact-golang)
297-
[![GitHub Stars](https://img.shields.io/github/stars/dbos-inc/dbos-transact-golang?style=social)](https://github.com/dbos-inc/dbos-transact-golang)
326+
[![GitHub Stars](https://img.shields.io/github/stars/dbos-inc/dbos-transact-golang?style=social)](https://github.com/dbos-inc/dbos-transact-golang)

0 commit comments

Comments
 (0)