Skip to content

Commit

Permalink
Go in concepts pages
Browse files Browse the repository at this point in the history
  • Loading branch information
jackkleeman committed Aug 22, 2024
1 parent 6be1506 commit b6800c8
Show file tree
Hide file tree
Showing 14 changed files with 571 additions and 11 deletions.
76 changes: 76 additions & 0 deletions code_snippets/go/concepts/foodordering.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package concepts

import restate "github.com/restatedev/sdk-go"

type OrderProcessor struct{}

// <start_here>
// <mark_1>
func (OrderProcessor) Process(ctx restate.ObjectContext, order Order) error {
// </mark_1>
// 1. Set status
// <mark_4>
restate.Set(ctx, "status", Status_CREATED)
// </mark_4>

// 2. Handle payment
// <mark_5>
token := restate.Rand(ctx).UUID().String()
paid, err := restate.Run(ctx, func(ctx restate.RunContext) (bool, error) {
return paymentClnt.Charge(ctx, order.Id, token, order.TotalCost)
})
if err != nil {
return err
}
// </mark_5>

if !paid {
// <mark_4>
restate.Set(ctx, "status", Status_REJECTED)
// </mark_4>
return nil
}

// 3. Wait until the requested preparation time
// <mark_4>
restate.Set(ctx, "status", Status_SCHEDULED)
// </mark_4>
restate.Sleep(ctx, order.DeliveryDelay)

// 4. Trigger preparation
// <mark_3>
preparationAwakeable := restate.Awakeable[restate.Void](ctx)
// <mark_5>
restate.Run(ctx, func(ctx restate.RunContext) (restate.Void, error) {
return restate.Void{}, restaurant.Prepare(order.Id, preparationAwakeable.Id())
})
// </mark_5>
// </mark_3>
// <mark_4>
restate.Set(ctx, "status", Status_IN_PREPARATION)
// </mark_4>

// <mark_3>
if _, err := preparationAwakeable.Result(); err != nil {
return err
}
// </mark_3>
// <mark_4>
restate.Set(ctx, "status", Status_SCHEDULING_DELIVERY)
// </mark_4>

// 5. Find a driver and start delivery
// <mark_2>
if _, err := restate.Object[restate.Void](ctx, "DeliveryManager", order.Id, "StartDelivery").
Request(order); err != nil {
return err
}
// </mark_2>
// <mark_4>
restate.Set(ctx, "status", Status_DELIVERED)
// </mark_4>

return nil
}

// <end_here>
50 changes: 50 additions & 0 deletions code_snippets/go/concepts/invocations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package concepts

import (
"time"

restate "github.com/restatedev/sdk-go"
)

type MyService struct{}

/*
// <start_rpc_call>
func (MyService) MyRestateHandler(ctx restate.Context) error {
// focus
greet, err := restate.
// focus
Service[string](ctx, "Greeter", "Greet").
// focus
Request("Hi")
return err
}
// <end_rpc_call>
// <start_one_way_call>
func (MyService) MyRestateHandler(ctx restate.Context) error {
// focus
restate.
// focus
ServiceSend(ctx, "Greeter", "Greet").
// focus
Send("Hi")
return nil
}
// <end_one_way_call>
*/

// <start_delayed_call>
func (MyService) MyRestateHandler(ctx restate.Context) error {
// focus
restate.
// focus
ServiceSend(ctx, "Greeter", "Greet").
// focus
Send("Hi", restate.WithDelay(1*time.Second))
return nil
}

// <end_delayed_call>
115 changes: 115 additions & 0 deletions code_snippets/go/concepts/services/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package main

import (
"context"
"fmt"
"log"
"math/rand"
"os"

restate "github.com/restatedev/sdk-go"
"github.com/restatedev/sdk-go/server"
)

type RoleUpdate struct{}

// <start_here>
// <mark_2>
func (RoleUpdate) ApplyRoleUpdate(ctx restate.Context, update UpdateRequest) error {
// </mark_2>

// <mark_1>
success, err := restate.Run(ctx, func(ctx restate.RunContext) (bool, error) {
return applyUserRole(update.UserId, update.Role)
})
if err != nil {
return err
}
// </mark_1>
// <mark_3>
if !success {
return nil
}
// </mark_3>

// <mark_3>
for _, permission := range update.Permissions {
// </mark_3>
// <mark_1>
if _, err := restate.Run(ctx, func(ctx restate.RunContext) (restate.Void, error) {
return restate.Void{}, applyPermission(update.UserId, permission)
}); err != nil {
return err
}
// </mark_1>
// <mark_3>
}
// </mark_3>

return nil
}

func main() {
if err := server.NewRestate().
Bind(restate.Reflect(RoleUpdate{})).
Start(context.Background(), ":9080"); err != nil {
log.Fatal(err)
}
}

// <end_here>

type UserRole struct {
RoleKey string
RoleDescription string
}

type Permission struct {
PermissionKey string
Setting string
}

type UpdateRequest struct {
UserId string
Role UserRole
Permissions []Permission
}

var killProcess = os.Getenv("CRASH_PROCESS") == "true"

func maybeCrash(probability float64) error {
if rand.Float64() < probability {
log.Println("A failure happened!")

if killProcess {
log.Fatal("--- CRASHING THE PROCESS ---")
} else {
return fmt.Errorf("A failure happened!")
}
}
return nil
}

func applyUserRole(
userId string,
userRole UserRole,
) (bool, error) {
if err := maybeCrash(0.3); err != nil {
return false, err
}
log.Printf(`>>> Applied role %s for user %s\n`, userRole.RoleKey, userId)
return true, nil
}

func applyPermission(
userId string,
permission Permission,
) error {
if err := maybeCrash(0.2); err != nil {
return err
}
log.Printf(
">>> Applied permission %s:%2 for user %s\n", permission.PermissionKey, permission.Setting, userId,
)
return nil
}
44 changes: 44 additions & 0 deletions code_snippets/go/concepts/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package concepts

import (
"context"
"time"
)

type Status int

const (
Status_NEW Status = iota
Status_CREATED
Status_SCHEDULED
Status_IN_PREPARATION
Status_SCHEDULING_DELIVERY
Status_WAITING_FOR_DRIVER
Status_IN_DELIVERY
Status_DELIVERED
Status_REJECTED
Status_CANCELLED
Status_UNKNOWN
)

type Order struct {
Id string
TotalCost int
DeliveryDelay time.Duration
}

type PaymentClient struct{}

func (PaymentClient) Charge(ctx context.Context, id string, token string, amount int) (bool, error) {
return true, nil
}

var paymentClnt PaymentClient

type RestaurantClient struct{}

func (RestaurantClient) Prepare(id string, cb string) error {
return nil
}

var restaurant = RestaurantClient{}
71 changes: 71 additions & 0 deletions code_snippets/go/concepts/virtualobjects/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"context"
"fmt"
"log"

restate "github.com/restatedev/sdk-go"
"github.com/restatedev/sdk-go/server"
)

type Greeter struct{}

// <start_here>
// <mark_1>
// <mark_3>
func Greet(ctx restate.ObjectContext, greeting string) (string, error) {
// </mark_3>
// </mark_1>
// <mark_2>
count, err := restate.Get[int](ctx, "count")
if err != nil {
return "", err
}
count++
restate.Set(ctx, "count", count)
// </mark_2>
// <mark_1>
return fmt.Sprintf(
"%s %s for the %d-th time.",
greeting, restate.Key(ctx), count,
), nil
// </mark_1>
}

// <mark_1>
// <mark_3>
func Ungreet(ctx restate.ObjectContext) (string, error) {
// </mark_3>
// </mark_1>
// <mark_2>
count, err := restate.Get[int](ctx, "count")
if err != nil {
return "", err
}
// </mark_2>
if count > 0 {
// <mark_2>
count--
// </mark_2>
}
// <mark_2>
restate.Set(ctx, "count", count)
// </mark_2>
// <mark_1>
return fmt.Sprintf(
"Dear %s, taking one greeting back: %d.",
restate.Key(ctx), count,
), nil
// </mark_1>
}

func main() {
if err := server.NewRestate().
Bind(restate.Reflect(Greeter{})).
Start(context.Background(), ":9080"); err != nil {
log.Fatal(err)
}
}

// <end_here>
14 changes: 14 additions & 0 deletions code_snippets/go/develop/kafka.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package develop

import restate "github.com/restatedev/sdk-go"

type KafkaService struct{}

func (KafkaService) MyEventHandler(ctx restate.Context, name string) error {
_ =
// <start_headers>
ctx.Request().Headers
// <end_headers>

return nil
}
Loading

0 comments on commit b6800c8

Please sign in to comment.