1
0
Fork 0
mirror of https://github.com/postmannen/ctrl.git synced 2024-12-14 12:37:31 +00:00
ctrl/message_and_subject.go
postmannen 3a31ced938 Squashed commit of the following:
implemented reading and embedding the content of a local file with {{CTRL_FILE}}

fixed error with not found filename in copy test, remove debug logs

seedfile: removed deletion, and changed file permissions to 600

created flags for profiling

renamed startup.subscriber to startup.startProcess

created a separate method for helloPublisher

removed processKind, og removed not needed file check in copy request

removed sams from channels

removed publisher channel on subject, and messages to publish are now directly published from the newMessagesCh

removed no longer needed compression and serialization flags.

all messaging are using zstd for compression, and cbor for serializing

added functions for handling cbor serializing and zstd compression, and swapped out json marshaling of jetstream message data with cbor and zstd

added flag for max jetstream messages to keep on broker per subject
2024-12-03 16:17:33 +01:00

147 lines
6.1 KiB
Go

package ctrl
import (
"fmt"
"log"
"os"
)
// --- Message
type Message struct {
_ struct{} `cbor:",toarray"`
// The node to send the message to.
ToNode Node `json:"toNode" yaml:"toNode"`
// ToNodes to specify several hosts to send message to in the
// form of an slice/array.
// The ToNodes field is only a concept that exists when messages
// are injected f.ex. on a socket, and there they are directly
//converted into separate node messages for each node, and from
// there the ToNodes field is not used any more within the system.
// With other words, a message that exists within ctrl is always
// for just for a single node.
ToNodes []Node `json:"toNodes,omitempty" yaml:"toNodes,omitempty"`
// JetstreamToNode, the topic used to prefix the stream name with
// with the format NODES.<JetstreamToNode> .
JetstreamToNode Node `json:"jetstreamToNode" yaml:"jetstreamToNode"`
// The Unique ID of the message
ID int `json:"id" yaml:"id"`
// The actual data in the message. This is typically where we
// specify the cli commands to execute on a node, and this is
// also the field where we put the returned data in a reply
// message.
Data []byte `json:"data" yaml:"data"`
// Method, what request type to use, like REQCliCommand, REQHttpGet..
Method Method `json:"method" yaml:"method"`
// Additional arguments that might be needed when executing the
// method. Can be f.ex. an ip address if it is a tcp sender, or the
// shell command to execute in a cli session.
MethodArgs []string `json:"methodArgs" yaml:"methodArgs"`
// ArgSignature is the ed25519 signature of the methodArgs.
ArgSignature []byte `json:"argSignature" yaml:"argSignature"`
// ReplyMethod, is the method to use for the reply message.
// By default the reply method will be set to log to file, but
// you can override it setting your own here.
ReplyMethod Method `json:"replyMethod" yaml:"replyMethod"`
// Additional arguments that might be needed when executing the reply
// method. Can be f.ex. an ip address if it is a tcp sender, or the
// shell command to execute in a cli session.
ReplyMethodArgs []string `json:"replyMethodArgs" yaml:"replyMethodArgs"`
// IsReply are used to tell that this is a reply message. By default
// the system sends the output of a request method back to the node
// the message originated from. If it is a reply method we want the
// result of the reply message to be sent to the central server, so
// we can use this value if set to swap the toNode, and fromNode
// fields.
IsReply bool `json:"isReply" yaml:"isReply"`
// From what node the message originated
FromNode Node `json:"fromNode" yaml:"fromNode"`
// ACKTimeout for waiting for an ack message
ACKTimeout int `json:"ACKTimeout" yaml:"ACKTimeout"`
// RetryWait specified the time in seconds to wait between retries.
RetryWait int `json:"retryWait" yaml:"retryWait"`
// IsSubPublishedMsg enables timeout of publishing process, and is used together with process.isSubProcess to be able to terminate the sub processes publishers.
IsSubPublishedMsg bool `json:"isSubPublishedMsg" yaml:"isSubPublishedMsg"`
// Resend retries
Retries int `json:"retries" yaml:"retries"`
// The ACK timeout of the new message created via a request event.
ReplyACKTimeout int `json:"replyACKTimeout" yaml:"replyACKTimeout"`
// The retries of the new message created via a request event.
ReplyRetries int `json:"replyRetries" yaml:"replyRetries"`
// Timeout for long a process should be allowed to operate
MethodTimeout int `json:"methodTimeout" yaml:"methodTimeout"`
// Timeout for long a process should be allowed to operate
ReplyMethodTimeout int `json:"replyMethodTimeout" yaml:"replyMethodTimeout"`
// Directory is a string that can be used to create the
//directory structure when saving the result of some method.
// For example "syslog","metrics", or "metrics/mysensor"
// The type is typically used in the handler of a method.
Directory string `json:"directory" yaml:"directory"`
// FileName is used to be able to set a wanted name
// on a file being saved as the result of data being handled
// by a method handler.
FileName string `json:"fileName" yaml:"fileName"`
// PreviousMessage are used for example if a reply message is
// generated and we also need a copy of the details of the the
// initial request message.
PreviousMessage *Message
// Schedule
Schedule []int `json:"schedule" yaml:"schedule"`
}
// --- Subject
// Node is the type definition for the node who receive or send a message.
type Node string
// subject contains the representation of a subject to be used with one
// specific process
type Subject struct {
// node, the name of the node to receive the message.
ToNode string `json:"node" yaml:"toNode"`
// method, what is this message doing, etc. CLICommand, Syslog, etc.
Method Method `json:"method" yaml:"method"`
}
// newSubject will return a new variable of the type subject, and insert
// all the values given as arguments. It will create the channel
// to receive new messages on the specific subject.
// The function will also verify that there is a methodHandler defined
// for the Request type.
func newSubject(method Method, node string) Subject {
// Get the Event type for the Method.
ma := method.GetMethodsAvailable()
_, ok := ma.CheckIfExists(method)
//mh, ok := ma.Methodhandlers[method]
if !ok {
log.Printf("error: newSubject: no Event type specified for the method: %v\n", method)
os.Exit(1)
}
return Subject{
ToNode: node,
Method: method,
}
}
// newSubjectNoVerifyHandler will return a new variable of the type subject, and insert
// all the values given as arguments. It will create the channel
// to receive new messages on the specific subject.
// The function will not verify that there is a methodHandler defined
// for the Request type.
func newSubjectNoVerifyHandler(method Method, node string) Subject {
// Get the Event type for the Method.
return Subject{
ToNode: node,
Method: method,
}
}
// subjectName is the complete representation of a subject
type subjectName string
// Return a value of the subjectName for the subject as used with nats subject.
func (s Subject) name() subjectName {
return subjectName(fmt.Sprintf("%s.%s", s.ToNode, s.Method))
}