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

133 lines
4.5 KiB
Go
Raw Normal View History

package steward
import (
"bytes"
"encoding/gob"
"encoding/json"
"fmt"
"log"
"os"
)
// --- Message
type Message struct {
2021-03-11 16:14:43 +00:00
// The node to send the message to
2021-06-29 06:21:42 +00:00
ToNode Node `json:"toNode" yaml:"toNode"`
// The Unique ID of the message
ID int `json:"id" yaml:"id"`
// The actual data in the message
Data []string `json:"data" yaml:"data"`
2021-04-13 11:50:00 +00:00
// Method, what is this message doing, etc. CLI, syslog, etc.
Method Method `json:"method" yaml:"method"`
// 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"`
// From what node the message originated
2021-06-29 06:21:42 +00:00
FromNode Node
// ACKTimeout for waiting for an ack message
ACKTimeout int `json:"ACKTimeout" yaml:"ACKTimeout"`
// 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"`
2021-03-11 16:14:43 +00:00
// The retries of the new message created via a request event.
2021-04-13 12:37:17 +00:00
ReplyRetries int `json:"replyRetries" yaml:"replyRetries"`
2021-03-11 16:14:43 +00:00
// Timeout for long a process should be allowed to operate
MethodTimeout int `json:"methodTimeout" yaml:"methodTimeout"`
2021-04-07 05:00:40 +00:00
// 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 extension
2021-04-07 05:00:40 +00:00
// on a file being saved as the result of data being handled
// by a method handler.
FileName string `json:"fileName" yaml:"fileName"`
// operation are used to give an opCmd and opArg's.
Operation Operation `json:"operation"`
// 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
// done is used to signal when a message is fully processed.
// This is used for signaling back to the ringbuffer that we are
// done with processing a message, and the message can be removed
// from the ringbuffer and into the time series log.
2021-03-11 16:14:43 +00:00
done chan struct{}
}
// ---
2021-08-16 11:01:12 +00:00
// operation are used to specify opCmd and opArg's.
type Operation struct {
OpCmd string `json:"opCmd"`
OpArg json.RawMessage `json:"opArg"`
}
// ---
2021-04-01 08:05:14 +00:00
// gobEncodePayload will encode the message structure into gob
2021-08-16 11:01:12 +00:00
// binary format before putting it into a nats message.
func gobEncodeMessage(m Message) ([]byte, error) {
var buf bytes.Buffer
gobEnc := gob.NewEncoder(&buf)
err := gobEnc.Encode(m)
if err != nil {
return nil, fmt.Errorf("error: gob.Encode failed: %v", err)
}
return buf.Bytes(), nil
}
// --- Subject
2021-08-16 11:01:12 +00:00
// Node is the type definition for the node who receive or send a message.
2021-06-29 06:21:42 +00:00
type Node string
// subject contains the representation of a subject to be used with one
// specific process
type Subject struct {
2021-08-16 11:01:12 +00:00
// node, the name of the node to receive the message.
ToNode string `json:"node" yaml:"toNode"`
// messageType, command/event
CommandOrEvent CommandOrEvent `json:"commandOrEvent" yaml:"commandOrEvent"`
// method, what is this message doing, etc. CLICommand, Syslog, etc.
Method Method `json:"method" yaml:"method"`
2021-03-09 06:43:55 +00:00
// messageCh is used by publisher kind processes to read new messages
// to be published. The content on this channel have been routed here
// from routeMessagesToPublish in *server.
// This channel is only used for publishing processes.
messageCh chan Message
}
// newSubject will return a new variable of the type subject, and insert
// all the values given as arguments. It will also create the channel
// to receive new messages on the specific subject.
func newSubject(method Method, node string) Subject {
// Get the CommandOrEvent type for the Method.
ma := method.GetMethodsAvailable()
2021-06-29 06:21:42 +00:00
coe, ok := ma.Methodhandlers[method]
if !ok {
log.Printf("error: no CommandOrEvent type specified for the method: %v\n", method)
os.Exit(1)
}
return Subject{
ToNode: node,
CommandOrEvent: coe.getKind(),
Method: method,
messageCh: make(chan Message),
}
}
// subjectName is the complete representation of a subject
type subjectName string
2021-08-16 11:01:12 +00:00
// 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", s.ToNode, s.Method, s.CommandOrEvent))
}