diff --git a/examples/lang/fastcount.mcl b/examples/lang/fastcount.mcl new file mode 100644 index 00000000..c365b35b --- /dev/null +++ b/examples/lang/fastcount.mcl @@ -0,0 +1,32 @@ +import "fmt" +import "test" + +# XXX: Because our function engine is not synchronous, absurdly-fast function +# changing will result in these four files having vastly different values after +# a certain amount of time. We probably want to fix this eventually. +$count = test.fastcount() + +file "/tmp/mgmt-count0" { + content => fmt.printf("count is: %d\n", $count + 0), + state => $const.res.file.state.exists, +} + +file "/tmp/mgmt-count1" { + content => fmt.printf("count is: %d\n", $count + 1), + state => $const.res.file.state.exists, +} + +file "/tmp/mgmt-count2" { + content => fmt.printf("count is: %d\n", $count + 2), + state => $const.res.file.state.exists, +} + +file "/tmp/mgmt-count" { + content => fmt.printf("count is: %d\n", $count), + state => $const.res.file.state.exists, +} + +File["/tmp/mgmt-count0"] -> File["/tmp/mgmt-count1"] +File["/tmp/mgmt-count0"] -> File["/tmp/mgmt-count2"] +File["/tmp/mgmt-count1"] -> File["/tmp/mgmt-count"] +File["/tmp/mgmt-count2"] -> File["/tmp/mgmt-count"] diff --git a/lang/funcs/core/core.go b/lang/funcs/core/core.go index b08db521..03680273 100644 --- a/lang/funcs/core/core.go +++ b/lang/funcs/core/core.go @@ -35,6 +35,7 @@ import ( _ "github.com/purpleidea/mgmt/lang/funcs/core/regexp" _ "github.com/purpleidea/mgmt/lang/funcs/core/strings" _ "github.com/purpleidea/mgmt/lang/funcs/core/sys" + _ "github.com/purpleidea/mgmt/lang/funcs/core/test" _ "github.com/purpleidea/mgmt/lang/funcs/core/world" ) diff --git a/lang/funcs/core/test/fastcount_fact.go b/lang/funcs/core/test/fastcount_fact.go new file mode 100644 index 00000000..59f43949 --- /dev/null +++ b/lang/funcs/core/test/fastcount_fact.go @@ -0,0 +1,83 @@ +// Mgmt +// Copyright (C) 2013-2023+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package coretest + +import ( + "context" + + "github.com/purpleidea/mgmt/lang/funcs/facts" + "github.com/purpleidea/mgmt/lang/types" +) + +const ( + // FastCountFuncName is the name this fact is registered as. It's still a + // Func Name because this is the name space the fact is actually using. + FastCountFuncName = "fastcount" +) + +func init() { + facts.ModuleRegister(ModuleName, FastCountFuncName, func() facts.Fact { return &FastCountFact{} }) // must register the fact and name +} + +// FastCountFact is a fact that counts up as fast as possible from zero forever. +type FastCountFact struct { + init *facts.Init +} + +// String returns a simple name for this fact. This is needed so this struct can +// satisfy the pgraph.Vertex interface. +func (obj *FastCountFact) String() string { + return FastCountFuncName +} + +// Validate makes sure we've built our struct properly. It is usually unused for +// normal facts that users can use directly. +//func (obj *FastCountFact) Validate() error { +// return nil +//} + +// Info returns some static info about itself. +func (obj *FastCountFact) Info() *facts.Info { + return &facts.Info{ + Output: types.NewType("int"), + } +} + +// Init runs some startup code for this fact. +func (obj *FastCountFact) Init(init *facts.Init) error { + obj.init = init + return nil +} + +// Stream returns the changing values that this fact has over time. +func (obj *FastCountFact) Stream(ctx context.Context) error { + defer close(obj.init.Output) // always signal when we're done + + count := int64(0) + + // streams must generate an initial event on startup + for { + select { + case obj.init.Output <- &types.IntValue{V: count}: + count++ + + case <-ctx.Done(): + return nil + } + } +} diff --git a/lang/funcs/core/test/test.go b/lang/funcs/core/test/test.go new file mode 100644 index 00000000..0eee59f6 --- /dev/null +++ b/lang/funcs/core/test/test.go @@ -0,0 +1,23 @@ +// Mgmt +// Copyright (C) 2013-2023+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package coretest + +const ( + // ModuleName is the prefix given to all the functions in this module. + ModuleName = "test" +)