mirror of
https://github.com/postmannen/ctrl.git
synced 2024-12-14 12:37:31 +00:00
added sessions
This commit is contained in:
parent
6e9c06b2ec
commit
7bf4b356dd
2 changed files with 77 additions and 31 deletions
|
@ -8,6 +8,7 @@ import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
|
@ -21,17 +22,16 @@ const (
|
||||||
// delivered back in the reply ack message.
|
// delivered back in the reply ack message.
|
||||||
// The message should contain the unique ID of the
|
// The message should contain the unique ID of the
|
||||||
// command.
|
// command.
|
||||||
shellCommandReturnOutput messageType = iota
|
commandReturnOutput messageType = iota
|
||||||
// shellCommand, wait for and return the output
|
// shellCommand, wait for and return the output
|
||||||
// of the command in the ACK message. This means
|
// of the command in the ACK message. This means
|
||||||
// that the command should be executed immediately
|
// that the command should be executed immediately
|
||||||
// and that we should get the confirmation that it
|
// and that we should get the confirmation that it
|
||||||
// was successful or not.
|
// was successful or not.
|
||||||
shellCommandReturnAck messageType = iota
|
eventReturnAck messageType = iota
|
||||||
// eventCommand, just wait for the ACK that the
|
// eventCommand, just wait for the ACK that the
|
||||||
// message is received. What action happens on the
|
// message is received. What action happens on the
|
||||||
// receiving side is up to the received to decide.
|
// receiving side is up to the received to decide.
|
||||||
eventCommand messageType = iota
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
|
@ -45,38 +45,61 @@ type Message struct {
|
||||||
MessageType messageType
|
MessageType messageType
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
// session are represent the communication to one individual host
|
||||||
edgeID := "btship1"
|
type session struct {
|
||||||
// Create a connection to nats server, and publish a message.
|
messageID int
|
||||||
natsConn, err := nats.Connect("localhost", nil)
|
subject string
|
||||||
if err != nil {
|
hostID hostID
|
||||||
log.Printf("error: nats.Connect failed: %v\n", err)
|
}
|
||||||
|
|
||||||
|
type hostID string
|
||||||
|
|
||||||
|
type server struct {
|
||||||
|
natsConn *nats.Conn
|
||||||
|
sessions map[hostID]session
|
||||||
|
}
|
||||||
|
|
||||||
|
func newServer(brokerAddress string) (*server, error) {
|
||||||
|
return &server{
|
||||||
|
sessions: make(map[hostID]session),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) Run() error {
|
||||||
|
// create the initial configuration for a sessions communicating with 1 host.
|
||||||
|
session := session{
|
||||||
|
messageID: 0,
|
||||||
|
hostID: "btship1",
|
||||||
}
|
}
|
||||||
defer natsConn.Close()
|
s.sessions["btship1"] = session
|
||||||
|
|
||||||
// There should be on IDCounter per Subject later on.
|
|
||||||
IDCounter := 0
|
|
||||||
|
|
||||||
|
// Loop creating one new message every second to simulate getting new
|
||||||
|
// messages to deliver.
|
||||||
for {
|
for {
|
||||||
m := Message{
|
m := getMessageToDeliver()
|
||||||
ID: IDCounter,
|
m.ID = s.sessions["btship1"].messageID
|
||||||
Data: []string{"uname", "-a"},
|
messageDeliver("btship1", m, s.natsConn)
|
||||||
MessageType: shellCommandReturnAck,
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Have a channel here to return
|
|
||||||
messageDeliver(edgeID, m, natsConn)
|
|
||||||
|
|
||||||
// Increment the counter for the next message to be sent.
|
// Increment the counter for the next message to be sent.
|
||||||
IDCounter++
|
session.messageID++
|
||||||
|
s.sessions["btship1"] = session
|
||||||
time.Sleep(time.Second * 1)
|
time.Sleep(time.Second * 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get MessageToDeliver will pick up the next message to be created.
|
||||||
|
// TODO: read this from local file or rest or....?
|
||||||
|
func getMessageToDeliver() Message {
|
||||||
|
return Message{
|
||||||
|
Data: []string{"uname", "-a"},
|
||||||
|
MessageType: eventReturnAck,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func messageDeliver(edgeID string, message Message, natsConn *nats.Conn) {
|
func messageDeliver(edgeID string, message Message, natsConn *nats.Conn) {
|
||||||
for {
|
for {
|
||||||
dataPayload, err := createDataPayload(message)
|
dataPayload, err := gobEncodePayload(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error: createDataPayload: %v\n", err)
|
log.Printf("error: createDataPayload: %v\n", err)
|
||||||
}
|
}
|
||||||
|
@ -118,7 +141,9 @@ func messageDeliver(edgeID string, message Message, natsConn *nats.Conn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDataPayload(m Message) ([]byte, error) {
|
// gobEncodePayload will encode the message structure along with its
|
||||||
|
// valued in gob binary format.
|
||||||
|
func gobEncodePayload(m Message) ([]byte, error) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
gobEnc := gob.NewEncoder(&buf)
|
gobEnc := gob.NewEncoder(&buf)
|
||||||
err := gobEnc.Encode(m)
|
err := gobEnc.Encode(m)
|
||||||
|
@ -128,3 +153,19 @@ func createDataPayload(m Message) ([]byte, error) {
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
s, err := newServer("localhost")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error: failed to connect to broker: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// Create a connection to nats server, and publish a message.
|
||||||
|
s.natsConn, err = nats.Connect("localhost", nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error: nats.Connect failed: %v\n", err)
|
||||||
|
}
|
||||||
|
defer s.natsConn.Close()
|
||||||
|
|
||||||
|
s.Run()
|
||||||
|
}
|
||||||
|
|
19
edge/main.go
19
edge/main.go
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
@ -19,17 +20,16 @@ const (
|
||||||
// delivered back in the reply ack message.
|
// delivered back in the reply ack message.
|
||||||
// The message should contain the unique ID of the
|
// The message should contain the unique ID of the
|
||||||
// command.
|
// command.
|
||||||
shellCommandReturnOutput messageType = iota
|
commandReturnOutput messageType = iota
|
||||||
// shellCommand, wait for and return the output
|
// shellCommand, wait for and return the output
|
||||||
// of the command in the ACK message. This means
|
// of the command in the ACK message. This means
|
||||||
// that the command should be executed immediately
|
// that the command should be executed immediately
|
||||||
// and that we should get the confirmation that it
|
// and that we should get the confirmation that it
|
||||||
// was successful or not.
|
// was successful or not.
|
||||||
shellCommandReturnAck messageType = iota
|
eventReturnAck messageType = iota
|
||||||
// eventCommand, just wait for the ACK that the
|
// eventCommand, just wait for the ACK that the
|
||||||
// message is received. What action happens on the
|
// message is received. What action happens on the
|
||||||
// receiving side is up to the received to decide.
|
// receiving side is up to the received to decide.
|
||||||
eventCommand messageType = iota
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
|
@ -42,7 +42,9 @@ type Message struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
edgeID := "btship1"
|
edgeID := flag.String("edgeID", "0", "some unique string to identify this Edge unit")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
// Create a connection to nats server, and publish a message.
|
// Create a connection to nats server, and publish a message.
|
||||||
natsConn, err := nats.Connect("localhost", nil)
|
natsConn, err := nats.Connect("localhost", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -56,7 +58,7 @@ func main() {
|
||||||
|
|
||||||
// Subscribe will start up a Go routine under the hood calling the
|
// Subscribe will start up a Go routine under the hood calling the
|
||||||
// callback function specified when a new message is received.
|
// callback function specified when a new message is received.
|
||||||
_, err = natsConn.Subscribe(edgeID, messageHandler(natsConn, reqMsgCh))
|
_, err = natsConn.Subscribe(*edgeID, listenForMessage(natsConn, reqMsgCh))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error: Subscribe failed: %v\n", err)
|
fmt.Printf("error: Subscribe failed: %v\n", err)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +69,7 @@ func main() {
|
||||||
msg := <-reqMsgCh
|
msg := <-reqMsgCh
|
||||||
fmt.Printf("%v\n", msg)
|
fmt.Printf("%v\n", msg)
|
||||||
switch msg.MessageType {
|
switch msg.MessageType {
|
||||||
case shellCommandReturnAck:
|
case eventReturnAck:
|
||||||
c := msg.Data[0]
|
c := msg.Data[0]
|
||||||
a := msg.Data[1:]
|
a := msg.Data[1:]
|
||||||
cmd := exec.Command(c, a...)
|
cmd := exec.Command(c, a...)
|
||||||
|
@ -81,7 +83,10 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func messageHandler(natsConn *nats.Conn, reqMsgCh chan Message) func(req *nats.Msg) {
|
// Listen for message will send an ACK message back to the sender,
|
||||||
|
// and put the received incomming message on the reqMsg channel
|
||||||
|
// for further processing.
|
||||||
|
func listenForMessage(natsConn *nats.Conn, reqMsgCh chan Message) func(req *nats.Msg) {
|
||||||
return func(req *nats.Msg) {
|
return func(req *nats.Msg) {
|
||||||
message := Message{}
|
message := Message{}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue