package main
import (
"context"
"errors"
"fmt"
"sync/atomic"
"time"
amtele "github.com/pancsta/asyncmachine-go/pkg/telemetry"
amprom "github.com/pancsta/asyncmachine-go/pkg/telemetry/prometheus"
amgen "github.com/pancsta/asyncmachine-go/tools/generator"
"golang.org/x/sync/errgroup"
"github.com/pancsta/asyncmachine-go/examples/mach_template/states"
amhelp "github.com/pancsta/asyncmachine-go/pkg/helpers"
am "github.com/pancsta/asyncmachine-go/pkg/machine"
arpc "github.com/pancsta/asyncmachine-go/pkg/rpc"
)
var ss = states .MachTemplateStates
type S = am .S
func init() {
amhelp .EnableDebugging (true )
}
func main() {
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach , err := NewTemplate (ctx , 0 )
if err != nil {
panic (err )
}
mach .Add (S {ss .Start , ss .Bar }, nil )
ch := make (chan []string , 1 )
mach .Add1 (ss .Channel , Pass (&A {
ReturnCh : ch ,
}))
fmt .Printf ("%v" , <-ch )
bazDone := make (chan struct {})
go func () {
done := mach .WhenTicks (ss .BazDone , 100 , nil )
for range 100 {
mach .Add1 (ss .Baz , Pass (&A {
Addr : "localhost:8090" ,
}))
}
<-done
close (bazDone )
}()
<-mach .WhenNot1 (ss .Bar , nil )
mach .Add1 (ss .Disposing , nil )
<-mach .When1 (ss .Disposed , nil )
mach .Dispose ()
<-mach .WhenDisposed ()
}
func NewTemplate (ctx context .Context , num int ) (*am .Machine , error ) {
handlers := &TemplateHandlers {
p : amhelp .Pool (10 ),
bazP : amhelp .Pool (1 ),
}
mach , err := am .NewCommon (ctx , "templ" , states .MachTemplateSchema , ss .Names (),
handlers , nil , &am .Opts {Tags : []string {"tag:val" , "tag2" }})
if err != nil {
return nil , err
}
handlers .Mach = mach
mach .SetGroups (states .MachTemplateGroups , states .MachTemplateStates )
mach .SemLogger ().SetLevel (am .LogChanges )
mach .SemLogger ().SetArgsMapper (LogArgs )
amhelp .MachDebugEnv (mach )
arpc .MachReplEnv (mach )
amprom .MachMetricsEnv (mach )
err = amgen .MachDashboardEnv (mach )
if err != nil {
mach .AddErr (err , nil )
}
err = amtele .MachBindOtelEnv (mach )
if err != nil {
mach .AddErr (err , nil )
}
tracer := &Tracer {}
err = mach .BindTracer (tracer )
if err != nil {
return nil , err
}
return mach , nil
}
type TemplateHandlers struct {
*am .ExceptionHandler
Mach *am .Machine
p *errgroup .Group
bazP *errgroup .Group
}
func (h *TemplateHandlers ) FooState (e *am .Event ) {
ctx := h .Mach .NewStateCtx (ss .Bar )
h .p .Go (func () error {
if ctx .Err () != nil {
return nil
}
fmt .Println ("FooState" )
return nil
})
}
func (h *TemplateHandlers ) BarExit (e *am .Event ) bool {
return h .Mach .Tick (ss .Baz ) > h .Mach .Tick (ss .Bar )*10
}
func (h *TemplateHandlers ) BazState (e *am .Event ) {
args := ParseArgs (e .Args )
addr := args .Addr
ctx := h .Mach .NewStateCtx (ss .Start )
h .bazP .Go (func () error {
if !amhelp .Wait (ctx , time .Second ) {
_ = AddErrExample (e , h .Mach , nil , nil )
return nil
}
fmt .Println ("BazState: " + addr )
h .Mach .Add1 (ss .BazDone , nil )
return nil
})
}
func (h *TemplateHandlers ) BazDoneState (e *am .Event ) {
h .Mach .Remove1 (ss .Bar , nil )
}
func (h *TemplateHandlers ) ChannelEnter (e *am .Event ) bool {
args := ParseArgs (e .Args )
return args != nil && cap (args .ReturnCh ) > 0
}
func (h *TemplateHandlers ) ChannelState (e *am .Event ) {
ParseArgs (e .Args ).ReturnCh <- []string {"hello" , "machines" }
}
const APrefix = "am_node"
type A struct {
Id string `log:"id"`
Addr string `log:"addr"`
ReturnCh chan <- []string
}
type ARpc struct {
Id string `log:"id"`
Addr string `log:"addr"`
}
func ParseArgs (args am .A ) *A {
if r , ok := args [APrefix ].(*ARpc ); ok {
return amhelp .ArgsToArgs (r , &A {})
} else if r , ok := args [APrefix ].(ARpc ); ok {
return amhelp .ArgsToArgs (&r , &A {})
}
if a , _ := args [APrefix ].(*A ); a != nil {
return a
}
return &A {}
}
func Pass (args *A ) am .A {
return am .A {APrefix : args }
}
func PassRpc (args *A ) am .A {
return am .A {APrefix : amhelp .ArgsToArgs (args , &ARpc {})}
}
func LogArgs (args am .A ) map [string ]string {
a := ParseArgs (args )
if a == nil {
return nil
}
return amhelp .ArgsToLogMap (a , 0 )
}
var ErrExample = errors .New ("error example" )
func AddErrExample (
event *am .Event , mach *am .Machine , err error , args am .A ,
) error {
if err != nil {
err = fmt .Errorf ("%w: %w" , ErrExample , err )
} else {
err = ErrExample
}
mach .EvAddErrState (event , ss .ErrExample , err , args )
return err
}
type Tracer struct {
*am .NoOpTracer
dirty atomic .Bool
}
func (t *Tracer ) TransitionEnd (transition *am .Transition ) {
t .dirty .Store (true )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .