natsrouter

package module
v1.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 21, 2024 License: MIT Imports: 10 Imported by: 0

README

NATSRouter Go Report Card

natsrouter

A high performance NATS client router that scales well

Trie management derived from Julien Schmidt's httprouter, but adapted to the notation of the NATS topics

Install

go get github.com/mondora/natsrouter/v2

Usage example

Basic complete example

package main

import (
	"log"
	"time"

	"github.com/mondora/natsrouter/v2"
)

type Config struct {
	nMux *natsrouter.Router
	// ...
}

// NatsMsgFake simil to nats.Msg
type NatsMsgFake struct {
	Data    []byte
	Subject string
	Sub     *struct {
		Subject string
	}
}

type SubMsg struct {
	msg *NatsMsgFake
	sub string
}

func (sm *SubMsg) GetMsg() interface{} {
	return sm.msg
}

func (sm *SubMsg) GetSubject() string {
	return sm.sub
}

func NewSubjectMsg(natsMsg *NatsMsgFake /*nats.Msg*/) natsrouter.SubjectMsg {
	subMsg := &SubMsg{
		msg: natsMsg,
		sub: natsMsg.Subject,
	}

	return subMsg
}

type Pipeline struct {
	cfg *Config
	msg *NatsMsgFake
}

func NewListenerPipeline(cfg *Config, msg *NatsMsgFake) *Pipeline {
	return &Pipeline{
		cfg: cfg,
		msg: msg,
	}
}

func (p *Pipeline) processMessage(action string) {
	log.Printf("action: %s - path: %s - data: %s\n", action, p.msg.Subject, string(p.msg.Data))
}

func (p *Pipeline) processDefault() {
	log.Printf("unmanaged path: %s\n", p.msg.Sub.Subject)
}

// ...

func (cfg *Config) SubscribeListener() {
	// "input.:guid.v1.ping.>" OR "input.*.v1.ping.>"
	cfg.nMux.Handle("input.*.v1.ping.>", 1, func(msg natsrouter.SubjectMsg, ps natsrouter.Params, message interface{}) {
		m := message.(*Pipeline)
		m.processMessage("PING")
	})
	// "input.:guid.v1.msg.>" (OR "input.*.v1.msg.>")
	cfg.nMux.Handle("input.*.v1.msg.>", 1, func(msg natsrouter.SubjectMsg, ps natsrouter.Params, message interface{}) {
		m := message.(*Pipeline)
		m.processMessage("MSG")
	})
	// Default. Rank 2 avoid collision with other valid subject ("input.*.v1.ping.>" or "input.*.v1.msg.>")
	cfg.nMux.Handle("input.*.v1.>", 2, func(msg natsrouter.SubjectMsg, ps natsrouter.Params, message interface{}) {
		m := message.(*Pipeline)
		m.processDefault()
	})
	// ...
	// queue subscribe subject must be a larger than the subjects related to the various Handlers
	// es. "input.*.v1.>" is wider than "input.*.v1.msg.>"
	// TODO enable QueueSubscribe with real NATS connection
	// _, err := natsCli.QueueSubscribe("input.*.v1.>", queueName, cfg.listenerHandler)
	// ...
}

func (cfg *Config) listenerHandler(msg *NatsMsgFake) {
	message := NewListenerPipeline(cfg, msg)
	// manages incoming NATS message, scanning binary tree for all defined rank
	subMsg := NewSubjectMsg(msg)
	err := cfg.nMux.ServeNATSWithPayload(subMsg, message)
	if err != nil {
		// 404 Not Found
		log.Println("404 Not Found")
	}
}

func main() {
	cfg := &Config{
		nMux: natsrouter.New(),
	}
	cfg.SubscribeListener()
	// inject msg (simulate NATS incoming message)
	cfg.listenerHandler(&NatsMsgFake{
		Subject: "input.TEST.v1.msg.test_action",
		Data:    []byte("TEST DATA"),
	})
	time.Sleep(1 * time.Second)
	log.Println("DONE.")
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var MatchedRoutePathParam = "$matchedRoutePath" //nolint

MatchedRoutePathParam is the Param name under which the path of the matched route is stored, if Router.SaveMatchedRoutePath is set.

Functions

This section is empty.

Types

type Handle

type Handle func(*nats.Msg, Params, interface{})

Handle is a function that can be registered to a route to handle NATS requests. It has a third parameter for the values of wildcards (path variables).

type Param

type Param struct {
	Key   string
	Value string
}

Param is a single parameter, consisting of a key and a value.

type Params

type Params []Param

Params is a Param-slice, as returned by the router. The slice is ordered, the first TOPIC parameter is also the first slice value. It is therefore safe to read values by the index.

func (Params) ByName

func (ps Params) ByName(name string) string

ByName returns the value of the first Param which key matches the given name. If no matching Param is found, an empty string is returned.

func (Params) MatchedRoutePath

func (ps Params) MatchedRoutePath() string

MatchedRoutePath retrieves the path of the matched route. Router.SaveMatchedRoutePath must have been enabled when the respective handler was added, otherwise this function always returns an empty string.

type Router

type Router struct {

	// If enabled, adds the matched route path onto the request context
	// before invoking the handler.
	// The matched route path is only added to handlers of routes that were
	// registered when this option was enabled.
	SaveMatchedRoutePath bool

	// Function to handle panics recovered from NATS handlers.
	// The handler can be used to keep your server from crashing because of
	// unrecovered panics.
	PanicHandler func(*nats.Msg, interface{})
	// contains filtered or unexported fields
}

Router is a handler which can be used to dispatch requests to different handler functions via configurable routes

func New

func New() *Router

New returns a new initialized Router. Path auto-correction, including trailing slashes, is enabled by default.

func (*Router) Handle

func (r *Router) Handle(path string, rank int, handle Handle)

Handle registers a new request handle with the given path.

func (*Router) Lookup

func (r *Router) Lookup(path string, rank int) (Handle, Params, bool)

Lookup allows the manual lookup of a rank + path combo. This is e.g. useful to build a framework around this router. If the path was found, it returns the handle function and the path parameter values.

func (*Router) ServeNATS

func (r *Router) ServeNATS(msg *nats.Msg) error

ServeNATS makes the router implement interface.

func (*Router) ServeNATSWithPayload

func (r *Router) ServeNATSWithPayload(msg *nats.Msg, payload interface{}) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL