generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
remove next fsm event if transition fails
- Loading branch information
Showing
7 changed files
with
399 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package fsmnext | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
|
||
"github.com/TBD54566975/ftl/go-runtime/ftl" | ||
) | ||
|
||
// This FSM allows transitions moving forward through the alphabet | ||
// Each transition also declares the next state(s) to transition to using State | ||
// | ||
//ftl:retry 2 1s | ||
var fsm *ftl.FSMHandle | ||
|
||
func init() { | ||
fsm = ftl.FSM("fsm", | ||
ftl.Start(StateA), | ||
ftl.Transition(StateA, StateB), | ||
ftl.Transition(StateA, StateC), | ||
ftl.Transition(StateA, StateD), | ||
ftl.Transition(StateB, StateC), | ||
ftl.Transition(StateB, StateD), | ||
ftl.Transition(StateC, StateD), | ||
) | ||
} | ||
|
||
type State string | ||
|
||
const ( | ||
A State = "A" | ||
B State = "B" | ||
C State = "C" | ||
D State = "D" | ||
) | ||
|
||
type Event struct { | ||
Instance string | ||
NextStates []State // will schedule fsm.Next with these states progressively | ||
NextAttempts ftl.Option[int] // will call fsm.Next this many times. Once otherwise | ||
Error ftl.Option[string] // if present, returns this error after calling fsm.Next() as needed | ||
} | ||
|
||
//ftl:typealias | ||
type EventA Event | ||
|
||
//ftl:verb | ||
func StateA(ctx context.Context, in EventA) error { | ||
return handleEvent(ctx, Event(in)) | ||
} | ||
|
||
//ftl:typealias | ||
type EventB Event | ||
|
||
//ftl:verb | ||
func StateB(ctx context.Context, in EventB) error { | ||
return handleEvent(ctx, Event(in)) | ||
} | ||
|
||
//ftl:typealias | ||
type EventC Event | ||
|
||
//ftl:verb | ||
func StateC(ctx context.Context, in EventC) error { | ||
return handleEvent(ctx, Event(in)) | ||
} | ||
|
||
//ftl:typealias | ||
type EventD Event | ||
|
||
//ftl:verb | ||
func StateD(ctx context.Context, in EventD) error { | ||
return handleEvent(ctx, Event(in)) | ||
} | ||
|
||
//ftl:data export | ||
type Request struct { | ||
State State | ||
Event Event | ||
} | ||
|
||
//ftl:verb export | ||
func SendOne(ctx context.Context, in Request) error { | ||
return fsm.Send(ctx, in.Event.Instance, eventFor(in.Event, in.State)) | ||
} | ||
|
||
func handleEvent(ctx context.Context, in Event) error { | ||
if len(in.NextStates) == 0 { | ||
return nil | ||
} | ||
event := eventFor(Event{ | ||
Instance: in.Instance, | ||
NextStates: in.NextStates[1:], | ||
NextAttempts: in.NextAttempts, | ||
}, in.NextStates[0]) | ||
attempts := in.NextAttempts.Default(1) | ||
for i := range attempts { | ||
ftl.LoggerFromContext(ctx).Infof("scheduling next event for %s (%d/%d)", in.Instance, i+1, attempts) | ||
if err := fsm.Next(ctx, in.Instance, event); err != nil { | ||
return err | ||
} | ||
} | ||
if errStr, ok := in.Error.Get(); ok { | ||
return errors.New(errStr) | ||
} | ||
return nil | ||
} | ||
|
||
func eventFor(event Event, state State) any { | ||
switch state { | ||
case A: | ||
return EventA(event) | ||
case B: | ||
return EventB(event) | ||
case C: | ||
return EventC(event) | ||
case D: | ||
return EventD(event) | ||
default: | ||
panic("unknown state") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
module = "fsmnext" | ||
language = "go" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
module ftl/fsmnext | ||
|
||
go 1.22.5 | ||
|
||
require github.com/TBD54566975/ftl v1.1.5 | ||
|
||
require ( | ||
connectrpc.com/connect v1.16.2 // indirect | ||
connectrpc.com/grpcreflect v1.2.0 // indirect | ||
connectrpc.com/otelconnect v0.7.1 // indirect | ||
github.com/alecthomas/atomic v0.1.0-alpha2 // indirect | ||
github.com/alecthomas/concurrency v0.0.2 // indirect | ||
github.com/alecthomas/participle/v2 v2.1.1 // indirect | ||
github.com/alecthomas/types v0.16.0 // indirect | ||
github.com/alessio/shellescape v1.4.2 // indirect | ||
github.com/benbjohnson/clock v1.3.5 // indirect | ||
github.com/danieljoos/wincred v1.2.0 // indirect | ||
github.com/go-logr/logr v1.4.2 // indirect | ||
github.com/go-logr/stdr v1.2.2 // indirect | ||
github.com/godbus/dbus/v5 v5.1.0 // indirect | ||
github.com/hashicorp/cronexpr v1.1.2 // indirect | ||
github.com/jackc/pgpassfile v1.0.0 // indirect | ||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect | ||
github.com/jackc/pgx/v5 v5.6.0 // indirect | ||
github.com/jackc/puddle/v2 v2.2.1 // indirect | ||
github.com/jpillora/backoff v1.0.0 // indirect | ||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect | ||
github.com/mattn/go-isatty v0.0.20 // indirect | ||
github.com/multiformats/go-base36 v0.2.0 // indirect | ||
github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect | ||
github.com/swaggest/jsonschema-go v0.3.72 // indirect | ||
github.com/swaggest/refl v1.3.0 // indirect | ||
github.com/zalando/go-keyring v0.2.5 // indirect | ||
go.opentelemetry.io/otel v1.28.0 // indirect | ||
go.opentelemetry.io/otel/metric v1.28.0 // indirect | ||
go.opentelemetry.io/otel/trace v1.28.0 // indirect | ||
golang.org/x/crypto v0.25.0 // indirect | ||
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect | ||
golang.org/x/mod v0.19.0 // indirect | ||
golang.org/x/net v0.27.0 // indirect | ||
golang.org/x/sync v0.7.0 // indirect | ||
golang.org/x/sys v0.22.0 // indirect | ||
golang.org/x/text v0.16.0 // indirect | ||
google.golang.org/protobuf v1.34.2 // indirect | ||
) | ||
|
||
replace github.com/TBD54566975/ftl => ./../../../../../.. |
Oops, something went wrong.