Files
mq/publisher.go
2024-09-28 08:31:45 +05:45

96 lines
2.1 KiB
Go

package mq
import (
"context"
"encoding/json"
"fmt"
"net"
)
type Publisher struct {
id string
opts Options
}
func NewPublisher(id string, opts ...Option) *Publisher {
options := defaultOptions()
for _, opt := range opts {
opt(&options)
}
pub := &Publisher{id: id}
if options.closeHandler == nil {
options.closeHandler = pub.onClose
}
if options.errorHandler == nil {
options.errorHandler = pub.onError
}
pub.opts = options
return pub
}
func (p *Publisher) Publish(ctx context.Context, queue string, task Task) error {
conn, err := net.Dial("tcp", p.opts.brokerAddr)
if err != nil {
return fmt.Errorf("failed to connect to broker: %w", err)
}
defer conn.Close()
ctx = SetHeaders(ctx, map[string]string{
PublisherKey: p.id,
ContentType: TypeJson,
})
cmd := Command{
ID: NewID(),
Command: PUBLISH,
Queue: queue,
MessageID: task.ID,
Payload: task.Payload,
}
return Write(ctx, conn, cmd)
}
func (p *Publisher) onClose(ctx context.Context, conn net.Conn) error {
fmt.Println("Publisher Connection closed", p.id, conn.RemoteAddr())
return nil
}
func (p *Publisher) onError(ctx context.Context, conn net.Conn, err error) {
fmt.Println("Error reading from publisher connection:", err, conn.RemoteAddr())
}
func (p *Publisher) Request(ctx context.Context, queue string, task Task) (Result, error) {
conn, err := net.Dial("tcp", p.opts.brokerAddr)
if err != nil {
return Result{}, fmt.Errorf("failed to connect to broker: %w", err)
}
defer conn.Close()
ctx = SetHeaders(ctx, map[string]string{
PublisherKey: p.id,
ContentType: TypeJson,
})
cmd := Command{
ID: NewID(),
Command: REQUEST,
Queue: queue,
MessageID: task.ID,
Payload: task.Payload,
}
var result Result
err = Write(ctx, conn, cmd)
if err != nil {
return result, err
}
if p.opts.messageHandler == nil {
p.opts.messageHandler = func(ctx context.Context, conn net.Conn, message []byte) error {
err := json.Unmarshal(message, &result)
if err != nil {
return err
}
return conn.Close()
}
}
ReadFromConn(ctx, conn, p.opts.messageHandler, p.opts.closeHandler, p.opts.errorHandler)
return result, nil
}