Command Bus Library in Go
This is a lightweight and flexible Command Bus library for Go, inspired by the Command Bus design pattern. It allows you to decouple the sender of a request (command) from the handler of that request.
Features
- Decoupling: Separates the sender of a request (command) from its handler, enabling better separation of concerns and easier testing.
- Flexibility: Provides a simple and extensible API for defining commands and their handlers.
- Concurrency: Handles commands asynchronously, making it suitable for high-performance applications.
Installation
go get github.com/veerakumarak/go-commandbus
Usage
package main
import (
"encoding/json"
"fmt"
"github.com/veerakumarak/go-commandbus"
"time"
)
// Define commands
const (
PrintCommand commandbus.Command = "print_command"
GreetCommand = "greet_command"
)
// Define command payloads
type PrintCommandPayload struct {
Message string
}
type GreetCommandPayload struct {
Name string
}
// Define command handlers
func PrintCommandHandler(payload json.RawMessage) (json.RawMessage, error) {
// parse payload
var printCommandPayload PrintCommandPayload
if err := json.Unmarshal(payload, &printCommandPayload); err != nil {
return nil, err
}
// execute the command
time.Sleep(time.Second * 2)
fmt.Println(printCommandPayload)
// return the result
return nil, nil
}
func GreetCommandHandler(payload json.RawMessage) (json.RawMessage, error) {
// parse payload
var greetCommandPayload GreetCommandPayload
if err := json.Unmarshal(payload, &greetCommandPayload); err != nil {
return nil, err
}
// execute the command
fmt.Println(greetCommandPayload)
// return the result
return nil, nil
}
func main() {
// Supports sequential execution
bus := commandbus.New("default-command-bus")
// Supports concurrent execution of one or more tasks based on maxWorkers
//bus := commandbus.NewWithOptions("command-bus-2-100", 2, 100)
// Register command handlers
err := bus.Register(PrintCommand, PrintCommandHandler)
if err != nil {
fmt.Println(err)
return
}
err = bus.Register(GreetCommand, GreetCommandHandler)
if err != nil {
fmt.Println(err)
return
}
// Execute commands synchronously
payload, _ := json.Marshal(&PrintCommandPayload{Message: "Hello World"})
_ = bus.Execute(PrintCommand, payload)
payload, _ = json.Marshal(&GreetCommandPayload{Name: "Alice"})
_ = bus.Execute(GreetCommand, payload)
// Execute commands asynchronously
payload, _ := json.Marshal(&PrintCommandPayload{Message: "Hello World"})
_ = bus.Dispatch(PrintCommand, payload)
payload, _ = json.Marshal(&GreetCommandPayload{Name: "Alice"})
_ = bus.Dispatch(GreetCommand, payload)
bus.Shutdown()
}
The output will be
{Hello World}
{Alice}
{Alice}
{Hello World}
Contributing
Contributions are welcome! Feel free to open an issue or submit a pull request for any improvements or new features you'd like to see.
License
This project is licensed under the MIT License - see the LICENSE file for details.