Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
qjoly committed Aug 27, 2024
1 parent 800499d commit 7017f41
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 37 deletions.
1 change: 1 addition & 0 deletions coffee-maker/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/nats-io/nkeys v0.4.7 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
)
2 changes: 2 additions & 0 deletions coffee-maker/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA=
golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
Expand Down
25 changes: 18 additions & 7 deletions coffee-maker/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/nats-io/nats.go"
"github.com/nats-io/nats.go/jetstream"
"golang.org/x/exp/rand"
)

const (
Expand Down Expand Up @@ -38,11 +39,12 @@ func main() {
defer cancel()

cfgStream := jetstream.StreamConfig{
Replicas: 3,
Name: streamName,
Subjects: []string{subjects},
Storage: jetstream.FileStorage,
Retention: jetstream.WorkQueuePolicy,
Replicas: 3,
Name: streamName,
Subjects: []string{subjects},
Storage: jetstream.FileStorage,
Retention: jetstream.WorkQueuePolicy,
AllowDirect: true,
}

_, err = js.CreateOrUpdateStream(ctx, cfgStream)
Expand All @@ -64,8 +66,17 @@ func main() {
cc, err := cons.Consume(func(msg jetstream.Msg) {
fmt.Printf("New message from %s : %s ", msg.Subject(), string(msg.Data()))
msg.InProgress()
time.Sleep(10 * time.Millisecond)
msg.Ack()

number := rand.Intn(10)
if number == 0 {
fmt.Print("--- failed !")
msg.Nak()
} else {
// fmt.Print("- succeed")
time.Sleep(200 * time.Millisecond)
msg.Ack()
}

fmt.Printf("\n")
})

Expand Down
11 changes: 5 additions & 6 deletions controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const (
)

type controllerResponse struct {
Status string `json:"status"`
Status string `json:"status"` // success or error
Message string `json:"message"`
}

Expand All @@ -35,11 +35,10 @@ func main() {
Message: "The coffee has been successfully scheduled",
}

jsonData, err := json.Marshal(response)
if err != nil {
fmt.Println("Error marshaling to JSON:", err)
msg.Respond([]byte("fail"))
}
// Handle message

jsonData, _ := json.Marshal(response)

fmt.Printf("Status: %s, Message: %s\n", response.Status, response.Message)

msg.Respond(jsonData)
Expand Down
45 changes: 22 additions & 23 deletions routes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,34 @@ type controllerResponse struct {
Message string `json:"message"`
}

func sendOrderToController(order CoffeeOrder) error {
func sendOrderToController(order CoffeeOrder) (controllerResponse, error) {
var response controllerResponse
url := os.Getenv("NATS_URL")
if url == "" {
return errors.New("Please provide nats url in NATS_URL env")
return response, errors.New("Please provide nats url in NATS_URL env")
}

nc, _ := nats.Connect(url)
defer nc.Drain()

jsonData, err := json.Marshal(order)
if err != nil {
return errors.New("Error converting to JSON:" + err.Error())
return response, errors.New("Error converting to JSON:" + err.Error())

}

rep, err := nc.Request(subject, jsonData, 2*time.Second)
if err != nil {
fmt.Println(err.Error())
return err
return response, err
}

var response controllerResponse
err = json.Unmarshal(rep.Data, &response)
if err != nil {
return errors.New("can't unmarshall response from controller")
return response, errors.New("can't unmarshall response from controller")
}

return nil
return response, nil
}

func handleCoffeeOrder(w http.ResponseWriter, r *http.Request) {
Expand All @@ -73,29 +74,27 @@ func handleCoffeeOrder(w http.ResponseWriter, r *http.Request) {
return
}

var orderStatus string
responseTitle := "Thank you!"
orderStatus = "success"

response := fmt.Sprintf("Order received from %s : %s size coffee, %s beans, with %s and %s sugar(s).",
order.Name, order.Size, order.BeanType, order.Milk, order.SugarCount)
fmt.Println(response)
var controllerResponse controllerResponse

if order.Size == "" || order.BeanType == "" || order.Name == "" || order.SugarCount == "" || order.Milk == "" {
response = "Something's missing 🤔"
orderStatus = "error"
controllerResponse.Message = "Something's missing 🤔"
controllerResponse.Status = "error"
json.NewEncoder(w).Encode(map[string]string{"title": "Oh...", "message": controllerResponse.Message, "status": controllerResponse.Status})
return
}

if orderStatus != "failed" {
err = sendOrderToController(order)
if err != nil {
orderStatus = "error"
responseTitle = "Oh..."
response = "Sadly, we can't transfer your order to our backend 😢"
}
controllerResponse, err = sendOrderToController(order)
if err != nil {
fmt.Println(err.Error())
controllerResponse.Status = "error"
responseTitle = "Oh..."
controllerResponse.Message = "Sadly, we were not able to discuss with our backend system..."
}

json.NewEncoder(w).Encode(map[string]string{"title": responseTitle, "message": response, "status": orderStatus})
fmt.Println(controllerResponse)

json.NewEncoder(w).Encode(map[string]string{"title": responseTitle, "message": controllerResponse.Message, "status": controllerResponse.Status})

return
}
Expand Down
2 changes: 1 addition & 1 deletion routes/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ <h1>Order Your Coffee</h1>
<label for="soy_milk">Soy milk</label>
</div>
<label for="sugar_count">Sugar Count:</label>
<input type="number" id="sugar_count" name="sugar_count" min="0" max="3" required>
<input type="number" id="sugar_count" name="sugar_count" min="0" max="3" value=1 required>

<button type="submit">Order Coffee</button>
</form>
Expand Down
85 changes: 85 additions & 0 deletions stock-manager/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package main

import (
"database/sql"
"fmt"
"log"

_ "github.com/mattn/go-sqlite3"
"github.com/nats-io/nats.go"
)

// Message represents the structure of the data received from NATS
type Message struct {
ID int `json:"id"`
Name string `json:"name"`
Value string `json:"value"`
}

func main() {
// Connect to SQLite database
db, err := sql.Open("sqlite3", "./data.db")
if err != nil {
log.Fatal("Failed to open SQLite database:", err)
}
defer db.Close()

// Create a table if it doesn't exist
createTableSQL := `CREATE TABLE IF NOT EXISTS data (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"value" TEXT
);`
_, err = db.Exec(createTableSQL)
if err != nil {
log.Fatal("Failed to create table:", err)
}

// Connect to NATS server
nc, err := nats.Connect(nats.DefaultURL)
if err != nil {
log.Fatal("Failed to connect to NATS:", err)
}
defer nc.Close()

// Subscribe to a NATS subject
sub, err := nc.Subscribe("data.subject", func(m *nats.Msg) {
log.Printf("Received a message: %s", string(m.Data))

// Process the received message and store it in the database
err := processAndStore(db, m.Data)
if err != nil {
log.Println("Error processing and storing data:", err)
}
})
if err != nil {
log.Fatal("Failed to subscribe to subject:", err)
}

// Keep the service running
log.Println("Service is running... waiting for messages.")
select {} // Block forever

// Unsubscribe when finished
defer sub.Unsubscribe()
}

// Process and store the received data in the SQLite database
func processAndStore(db *sql.DB, data []byte) error {
// For simplicity, assume the data is a simple comma-separated string: "name,value"
var name, value string
n, err := fmt.Sscanf(string(data), "%s,%s", &name, &value)
if err != nil || n != 2 {
return fmt.Errorf("invalid data format")
}

// Insert data into the SQLite database
insertSQL := `INSERT INTO data (name, value) VALUES (?, ?)`
_, err = db.Exec(insertSQL, name, value)
if err != nil {
return fmt.Errorf("failed to insert data into database: %v", err)
}

log.Println("Data successfully stored in the database")
return nil
}

0 comments on commit 7017f41

Please sign in to comment.