package main
import (
"context"
"encoding/gob"
"errors"
"fmt"
"sync/atomic"
"time"
"github.com/joho/godotenv"
"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"
amss "github.com/pancsta/asyncmachine-go/pkg/states"
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"
)
var ss = states .MachTemplateStates
type S = am .S
func init() {
err := godotenv .Load ("example.env" )
if err != nil {
panic (err )
}
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 , am .Pass (&AChannel {
ReturnCh : ch ,
}))
fmt .Printf ("%v\n" , <-ch )
go func () {
done := mach .WhenTicks (ss .BazDone , 100 , nil )
for range 100 {
mach .Add1 (ss .Baz , am .Pass (&ABaz {
Addr : "localhost:8090" ,
}))
}
<-done
}()
<-mach .WhenNot1 (ss .Bar , nil )
mach .Add1 (ss .Disposing , nil )
<-mach .When1 (ss .Disposed , nil )
<-mach .WhenDisposed ()
fmt .Printf ("done" )
}
func NewTemplate (ctx context .Context , num int ) (*am .Machine , error ) {
handlers := &TemplateHandlers {
DisposedHandlers : &amss .DisposedHandlers {},
}
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 .PoolSetLimit (ss .Baz +am .SuffixState , 10 )
mach .SetGroups (states .MachTemplateGroups , states .MachTemplateStates )
mach .SemLogger ().SetLevel (am .LogChanges )
mach .SemLogger ().SetArgsMapper (amhelp .LogArgsMapper )
amhelp .MachDebugEnv (mach )
err , _ = arpc .MachReplEnv (mach , &arpc .ReplOpts {
AddrDir : "." ,
Args : ArgsRpc ,
})
if err != nil {
return nil , err
}
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
*amss .DisposedHandlers
Mach *am .Machine
}
var _ = ss .Foo
func (h *TemplateHandlers ) FooState (e *am .Event ) {
ctx := h .Mach .NewStateCtx (ss .Bar )
h .Mach .Fork (ctx , e , func () {
fmt .Println ("FooState" )
h .Mach .Go (ctx , func () {
fmt .Println ("FooState.Go" )
})
})
}
var _ = ss .Bar
func (h *TemplateHandlers ) BarExit (e *am .Event ) bool {
return h .Mach .Tick (ss .Baz ) > h .Mach .Tick (ss .Bar )*10
}
var _ = ss .Baz
func (h *TemplateHandlers ) BazState (e *am .Event ) {
args := am .ParseArgs [ABaz ](e .Args )
addr := args .Addr
ctx := h .Mach .NewStateCtx (ss .Start )
h .Mach .PoolFork (ctx , e , func () {
if !amhelp .Wait (ctx , time .Second ) {
_ = AddErrExample (e , h .Mach , nil , nil )
return
}
fmt .Println ("BazState: " + addr )
h .Mach .EvAdd1 (e , ss .BazDone , nil )
})
}
var _ = ss .BazDone
func (h *TemplateHandlers ) BazDoneState (e *am .Event ) {
h .Mach .EvRemove1 (e , ss .Bar , nil )
}
var _ = ss .Channel
func (h *TemplateHandlers ) ChannelEnter (e *am .Event ) bool {
args := am .ParseArgs [AChannel ](e .Args )
return args != nil && cap (args .ReturnCh ) > 0
}
func (h *TemplateHandlers ) ChannelState (e *am .Event ) {
am .ParseArgs [AChannel ](e .Args ).ReturnCh <- []string {"hello" , "machines" }
}
const APrefix = "template"
type Args struct {
am .ArgsBase `json:"-"`
}
func (Args ) ArgsPrefix () string {
return APrefix
}
type AChannel struct {
Args `json:"-"`
ReturnCh chan <- []string
}
func (AChannel ) ArgsState () string {
return ss .Channel
}
type ABaz struct {
Args `json:"-"`
Addr string `log:"addr"`
}
func (ABaz ) ArgsState () string {
return ss .Baz
}
func init() {
for _ , arg := range ArgsRpc {
gob .Register (arg )
}
}
var ArgsRpc = []am .ArgsApi {ABaz {}}
var ErrExample = errors .New ("error example" )
func AddErrExample (
event *am .Event , mach *am .Machine , err error , args am .A ,
) am .Result {
if err == nil {
return am .Executed
}
err = fmt .Errorf ("%w: %w" , ErrExample , err )
return mach .EvAddErrState (event , ss .ErrExample , err , args )
}
type Tracer struct {
*am .TracerNoOp
dirty atomic .Bool
}
func (t *Tracer ) TracerId () string {
return "mytrace"
}
func (t *Tracer ) TransitionEnd (transition *am .Transition ) {
t .dirty .Store (true )
}
The pages are generated with Golds v0.8.4 . (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 .