miso

package
v0.1.6 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2024 License: Apache-2.0 Imports: 42 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TagApiDocDesc  = "desc"
	TagApiDocXDesc = "xdesc"
)
View Source
const (
	// Service registration status - passing.
	ConsulStatusPassing = "passing"

	// Zero value for empty serviceId
	ServiceIdNil = "nil"
)
View Source
const (
	ServiceStatusUp   = "UP"
	ServiceStatusDown = "DOWN"
)
View Source
const (
	LOOPBACK_LOCALHOST = "localhost"
	LOOPBACK_127       = "127.0.0.1"
	LOCAL_IP_ANY       = "0.0.0.0"
)
View Source
const (
	// whether production mode is turned on (true/false)
	PropProdMode = "mode.production"

	/*
		------------------------------------

		Prop for App

		------------------------------------
	*/
	PropAppName = "app.name"

	/*
		------------------------------------

		Prop for Consul

		------------------------------------
	*/
	PropConsulEnabled                     = "consul.enabled"
	PropConsuleRegisterName               = "consul.registerName"
	PropConsulRegisterAddress             = "consul.registerAddress"
	PropConsulAddress                     = "consul.consulAddress"
	PropConsulHealthcheckUrl              = "consul.healthCheckUrl"
	PropConsulHealthCheckInterval         = "consul.healthCheckInterval"
	PropConsulHealthcheckTimeout          = "consul.healthCheckTimeout"
	PropConsulHealthCheckFailedDeregAfter = "consul.healthCheckFailedDeregisterAfter"
	PropConsulRegisterDefaultHealthcheck  = "consul.registerDefaultHealthCheck"
	PropConsulFetchServerInterval         = "consul.fetchServerInterval"
	PropConsulDeregisterUrl               = "consul.deregisterUrl"
	PropConsulEnableDeregisterUrl         = "consul.enableDeregisterUrl"
	PropConsulMetadata                    = "consul.metadata"

	/*
		------------------------------------

		Prop for ServiceDiscovery

		------------------------------------
	*/
	PropSDSubscrbe = "service-discovery.subscribe"

	PropServerEnabled                    = "server.enabled"
	PropServerHost                       = "server.host"
	PropServerPort                       = "server.port"
	PropServerGracefulShutdownTimeSec    = "server.gracefulShutdownTimeSec"
	PropServerPerfEnabled                = "server.perf.enabled"
	PropServerRequestLogEnabled          = "server.request-log.enabled"
	PropServerPropagateInboundTrace      = "server.trace.inbound.propagate"
	PropServerRequestValidateEnabled     = "server.validate.request.enabled"
	PropServerPprofEnabled               = "server.pprof.enabled"
	PropServerGenerateEndpointDocEnabled = "server.generate-endpoint-doc.enabled"
	PropServerGenerateEndpointDocFile    = "server.generate-endpoint-doc.file"
	PropServerRequestAutoMapHeader       = "server.request.mapping.header"
	PropServerGinValidationDisabled      = "server.gin.validation.disabled"

	PropTracingPropagationKeys = "tracing.propagation.keys"

	PropLoggingLevel                  = "logging.level"
	PropLoggingRollingFile            = "logging.rolling.file"
	PropLoggingRollingFileMaxAge      = "logging.file.max-age"
	PropLoggingRollingFileMaxSize     = "logging.file.max-size"
	PropLoggingRollingFileMaxBackups  = "logging.file.max-backups"
	PropLoggingRollingFileRotateDaily = "logging.file.rotate-daily"

	PropMetricsEnabled              = "metrics.enabled"
	PropMetricsRoute                = "metrics.route"
	PropMetricsAuthEnabled          = "metrics.auth.enabled"
	PropMetricsAuthBearer           = "metrics.auth.bearer"
	PropMetricsEnableMemStatsLogJob = "metrics.memstat.log.job.enabled"
	PropMetricsMemStatsLogJobCron   = "metrics.memstat.log.job.cron"

	PropConfigExtraFiles = "config.extra.files"
)
View Source
const (
	// Components like database that are essential and must be ready before anything else.
	BootstrapOrderL1 = -20

	// Components that are bootstraped before the web server, such as metrics stuff.
	BootstrapOrderL2 = -15

	// The web server or anything similar, bootstraping web server doesn't really mean that we will receive inbound requests.
	BootstrapOrderL3 = -10

	// Components that introduce inbound requests or job scheduling.
	//
	// When these components bootstrap, the server is considered truly running.
	// For example, service registration (for service discovery), MQ broker connection and so on.
	BootstrapOrderL4 = -5

	ExtraDesc         = "miso-Desc"
	ExtraScope        = "miso-Scope"
	ExtraResource     = "miso-Resource"
	ExtraQueryParam   = "miso-QueryParam"
	ExtraHeaderParam  = "miso-HeaderParam"
	ExtraJsonRequest  = "miso-JsonRequest"
	ExtraJsonResponse = "miso-JsonResponse"

	ScopePublic    = "PUBLIC"
	ScopeProtected = "PROTECTED"

	TagQueryParam  = "form"
	TagHeaderParam = "header"
)
View Source
const (
	XTraceId = "X-B3-TraceId"
	XSpanId  = "X-B3-SpanId"
)
View Source
const (
	TagValidationV1 = "validation" // name of validation tag
	TagValidationV2 = "valid"      // name of validation tag (v2)

	ValidMaxLen = "maxLen" // max length of a string, array, slice, e.g., `valid:"maxLen:10"`

	ValidNotEmpty = "notEmpty" // not empty, supports string, array, slice, map
	ValidNotNil   = "notNil"   // not nil, only validates slice, map, pointer, func

	// must be one of the values listed, e.g., 'valid:"member:PUBLIC|PROTECTED"', means that the tag value must be either PUBLIC or PROTECTED.
	// only string type is supported.
	ValidMember = "member"

	ValidPositive       = "positive"       // greater than 0, only supports int... or string type
	ValidPositiveOrZero = "positiveOrZero" // greater than or equal to 0, only supports int... or string type
	ValidNegative       = "negative"       // less than 0, only supports int... or string type
	ValidNegativeOrZero = "negativeOrZero" // less than or equal to 0, only supports int... or string type
	ValidNotZero        = "notZero"        // not zero, only supports int... or string type
	Validated           = "validated"      // mark a nested struct or pointer validated, nil pointer is ignored, one may combine "notNil,validated"
)
View Source
const (
	Bearer = "Bearer"
)
View Source
const (
	ConsulMetaRegisterTime = "miso-register_time"
)
View Source
const (
	DefaultPageLimit = 30
)
View Source
const (
	ErrCodeGeneric = "XXXX"
)

Variables

View Source
var (
	// Select Server randomly.
	RandomServerSelector ServerSelector = func(servers []Server) int {
		return rand.Int() % len(servers)
	}

	// Property based ServiceRegistry
	PropBasedServiceRegistry = HardcodedServiceRegistry{}

	// ServerList based ServiceRegistry
	//
	// Server selection can be customized by replacing the Rule.
	DynamicServiceRegistry = ServerListServiceRegistry{Rule: RandomServerSelector}

	ErrMissingServiceName      = errors.New("service name is required")
	ErrServiceInstanceNotFound = errors.New("unable to find any available service instance")
	ErrServerListNotFound      = errors.New("fail to find ServerList implemnetation")

	// Get ServerList implementation
	GetServerList func() ServerList
)
View Source
var (
	ValidateWalkTagCallbackDeprecated = util.WalkTagCallback{
		Tag:      TagValidationV1,
		OnWalked: validateOnWalked,
	}
	ValidateWalkTagCallback = util.WalkTagCallback{
		Tag:      TagValidationV2,
		OnWalked: validateOnWalked,
	}
)
View Source
var (
	ApiDocTypeAlias = map[string]string{
		"ETime":       "int64",
		"*ETime":      "int64",
		"*miso.ETime": "int64",
		"*util.ETime": "int64",
	}
)
View Source
var (

	// Api for Consul.
	ConsulApi = ConsulApiImpl{}
)
View Source
var (
	MetricsMemoryMatcher = regexp.MustCompile(`^/memory/.*`)
)
View Source
var (
	MisoDefaultClient *http.Client
)

Functions

func AddGetPipelineDocFunc added in v0.1.0

func AddGetPipelineDocFunc(f GetPipelineDocFunc)

Register func to supply PipelineDoc.

func AddHeaders

func AddHeaders(req *http.Request, headers map[string][]string)

Add http headers

func AddHealthIndicator added in v0.0.6

func AddHealthIndicator(hi HealthIndicator)

Add health indicator.

func AddPropagationKey

func AddPropagationKey(key string)

Add propagation key for tracing

func AddPropagationKeys added in v0.0.27

func AddPropagationKeys(keys ...string)

Add propagation key for tracing

func AddShutdownHook

func AddShutdownHook(hook func())

Register shutdown hook, hook should never panic

func AddXDesc added in v0.1.1

func AddXDesc(code string, desc string)

Associate xdesc value with the code appeared in field tag `xdesc:"..."`.

func ArgKeyVal

func ArgKeyVal(args []string) map[string][]string

Parse CLI args to key-value map

func BearerAuth added in v0.0.20

func BearerAuth(delegate http.Handler, getExpectedToken func() string) http.HandlerFunc

func BootstrapServer

func BootstrapServer(args []string)

Bootstrap server

This func will attempt to create http server, connect to MySQL, Redis or Consul based on the configuration loaded.

It also handles service registration/de-registration on Consul before Gin bootstraped and after SIGTERM/INTERRUPT signals are received.

Graceful shutdown for the http server is also enabled and can be configured through props.

To configure server, MySQL, Redis, Consul and so on, see PROPS_* in prop.go.

It's also possible to register callbacks that are triggered before/after server bootstrap

server.PreServerBootstrap(func(c Rail) error {
	// do something right after configuration being loaded, but server hasn't been bootstraped yet
});

server.PostServerBootstrapped(func(c Rail) error {
	// do something after the server bootstrap
});

// start the server
server.BootstrapServer(os.Args)

func BuildRollingLogFileWriter

func BuildRollingLogFileWriter(p NewRollingLogFileParam) *lumberjack.Logger

Create rolling file based logger

func ChainValidationError

func ChainValidationError(parentField string, e error) error

func ClientSkipTlsSecureCheck added in v0.0.4

func ClientSkipTlsSecureCheck()

Disable TLS certificate check.

func ConfigureLogging

func ConfigureLogging(rail Rail) error

Configure logging level and output target based on loaded configuration.

func ConsulBootstrap

func ConsulBootstrap(rail Rail) error

func ConsulBootstrapCondition added in v0.0.8

func ConsulBootstrapCondition(rail Rail) (bool, error)

func ContainsProp

func ContainsProp(prop string) bool

Check whether the prop exists

func CustomFormatter

func CustomFormatter() logrus.Formatter

Get custom formatter logrus

func Debug added in v0.0.8

func Debug(args ...interface{})

func DebugTimeOp

func DebugTimeOp(r Rail, start time.Time, name string)

Run timer for named operation and print result in log

e.g.,

defer DebugTimeOp(ec, time.Now(), "someOperation")

func Debugf added in v0.0.8

func Debugf(format string, args ...interface{})

func DefaultHealthCheck

func DefaultHealthCheck(ctx *gin.Context)

Create a default health check endpoint that simply doesn't nothing except returing 200

func DefaultMetricDesc added in v0.0.13

func DefaultMetricDesc(matcher *regexp.Regexp) []metrics.Description

func DefaultReadConfig

func DefaultReadConfig(args []string, rail Rail)

Default way to read config file.

Repetitively calling this method overides previously loaded config.

You can also use ReadConfig to load your custom configFile. This func is essentially:

LoadConfigFromFile(GuessConfigFilePath(args))

Notice that the loaded configuration can be overriden by the cli arguments as well by using `KEY=VALUE` syntax.

func DefaultRecovery

func DefaultRecovery(c *gin.Context, e interface{})

Default Recovery func

func DeregisterConsulService added in v0.0.28

func DeregisterConsulService() error

Deregister current service

func DispatchErrMsgJson

func DispatchErrMsgJson(c *gin.Context, msg string)

Dispatch error response in json format

func DispatchJson

func DispatchJson(c *gin.Context, body interface{})

Dispatch a json response

func DispatchJsonCode added in v0.0.18

func DispatchJsonCode(c *gin.Context, code int, body interface{})

Dispatch a json response

func EnableBasicAuth added in v0.0.30

func EnableBasicAuth(f func(username string, password string, url string, method string) bool)

Enable Basic authorization globally for all registered endpoints.

func Error added in v0.0.8

func Error(args ...interface{})

func Errorf added in v0.0.8

func Errorf(format string, args ...interface{})

func ExtractArgValue

func ExtractArgValue(args []string, predicate util.Predicate[string]) string

Parse CLI Arg to extract a value from arg, [key]=[value]

e.g.,

To look for 'configFile=?'.

path := ExtractArgValue(args, func(key string) bool { return key == "configFile" }).

func Fatal added in v0.0.20

func Fatal(args ...interface{})

func Fatalf added in v0.0.20

func Fatalf(format string, args ...interface{})

func FilterMetricDesc added in v0.0.13

func FilterMetricDesc(nameFilter func(name string) bool, kindFilter func(kind metrics.ValueKind) bool) []metrics.Description

func GetConfIntSlice

func GetConfIntSlice(prop string) []int

Get prop as int slice

func GetConsulClient

func GetConsulClient() *api.Client

Get the already created consul client.

InitConsulClient() must be called before this func.

If the client is not already created, this func will panic.

func GetCtxInt

func GetCtxInt(ctx context.Context, key string) (int, bool)

Get value from context as an int.

string is also formatted as int if possible.

func GetCtxStr

func GetCtxStr(ctx context.Context, key string) (string, bool)

Get value from context as a string

int*, unit*, float* types are formatted as string, other types are returned as empty string

func GetEnv

func GetEnv(key string) string

Get environment variable

func GetEnvElse

func GetEnvElse(key string, defVal string) string

Get environment variable with default value

func GetLocalIPV4

func GetLocalIPV4() string

Get local ipv4 address (excluding loopback address)

func GetPropBool

func GetPropBool(prop string) bool

Get prop as bool

func GetPropDur added in v0.0.14

func GetPropDur(prop string, unit time.Duration) time.Duration

Get prop as time.Duration

func GetPropInt

func GetPropInt(prop string) int

Get prop as int

func GetPropIntSlice

func GetPropIntSlice(prop string) []int

Get prop as int slice

func GetPropStr

func GetPropStr(prop string) string

Get prop as string

If the value is an argument that can be expanded, the actual value will be resolved if possible.

e.g, for "name" : "${secretName}".

This func will attempt to resolve the actual value for '${secretName}'.

func GetPropStrMap added in v0.0.14

func GetPropStrMap(prop string) map[string]string

Get prop as string based map.

func GetPropStrSlice added in v0.0.3

func GetPropStrSlice(prop string) []string

Get prop as string slice

func GetPropagationKeys

func GetPropagationKeys() []string

Get all existing propagation key

func GuessConfigFilePath

func GuessConfigFilePath(args []string) string

Guess config file path.

It first looks for the arg that matches the pattern "configFile=/path/to/configFile". If none is found, it's by default 'conf.yml'.

func HandleEndpointResult added in v0.0.23

func HandleEndpointResult(inb Inbound, rail Rail, result any, err error)

Handle endpoint's result using the configured EndpointResultHandler.

func HasProp

func HasProp(prop string) bool

Check whether the prop exists

func HasScheduledJobs added in v0.0.9

func HasScheduledJobs() bool

Whether scheduler is initialized

func Info added in v0.0.8

func Info(args ...interface{})

func Infof added in v0.0.8

func Infof(format string, args ...interface{})

func InitConsulClient added in v0.0.14

func InitConsulClient() error

Get or init new consul client

For the first time that the consul client is initialized, this func will look for prop:

"consul.consulAddress"

func IsConsulClientInitialized

func IsConsulClientInitialized() bool

Check whether consul client is initialized

func IsConsulServiceRegistered added in v0.0.13

func IsConsulServiceRegistered() bool

Check if current instance is registered on consul.

func IsDebugLevel

func IsDebugLevel() bool

Check whether current log level is DEBUG

func IsLocalAddress

func IsLocalAddress(address string) bool

Check whether the address is local (localhost/127.0.0.1)

func IsNoneErr added in v0.0.3

func IsNoneErr(err error) bool

Check if the error represents None

func IsProdMode

func IsProdMode() bool

Check whether we are running in production mode

func IsShuttingDown

func IsShuttingDown() bool

check if the server is shutting down

func JoinQueryParam

func JoinQueryParam(queryParams map[string][]string) string

Join query parameters

func LTimeOp

func LTimeOp(start time.Time, name string)

Run timer for named operation and print result

e.g.,

defer LTimeOp(ec, time.Now(), "someOperation")

func LoadConfigFromFile

func LoadConfigFromFile(configFile string, r Rail) error

Load config from file.

Calling this method overides previously loaded config.

func LoadConfigFromReader added in v0.0.29

func LoadConfigFromReader(reader io.Reader, r Rail) error

Load config from io Reader.

It's the caller's responsibility to close the provided reader.

Calling this method overides previously loaded config.

func LoadConfigFromStr added in v0.1.1

func LoadConfigFromStr(s string, r Rail) error

Load config from string.

Calling this method overides previously loaded config.

func LoadPropagationKeys added in v0.0.7

func LoadPropagationKeys(r Rail)

Read property and find propagation keys .

This func looks for following property.

"tracing.propagation.keys"

func ManualBootstrapPrometheus added in v0.0.13

func ManualBootstrapPrometheus()

Caller wants to bootstrap prometheus manually.

This is mainly used for gateway that implements handler for all endpoints.

func ManualPprofRegister added in v0.0.15

func ManualPprofRegister()

Registrer pprof debug endpoint manually.

func MarkServerShuttingDown

func MarkServerShuttingDown()

mark that the server is shutting down

func MustBind

func MustBind(rail Rail, c *gin.Context, ptr any)

Must bind request payload to the given pointer, else panic

func MustCompile added in v0.0.29

func MustCompile(fs embed.FS, s string) *template.Template

func NewDeleteRequest

func NewDeleteRequest(url string) (*http.Request, error)

Create DELETE request

func NewGetRequest

func NewGetRequest(url string) (*http.Request, error)

Create GET request

func NewHeadRequest

func NewHeadRequest(url string) (*http.Request, error)

Create HEAD request

func NewOptionsRequest

func NewOptionsRequest(url string) (*http.Request, error)

Create OPTIONS request

func NewPostRequest

func NewPostRequest(url string, body io.Reader) (*http.Request, error)

Create POST request

func NewPromCounter added in v0.0.6

func NewPromCounter(name string) prometheus.Counter

Create new Counter.

The Counter with this name is automatically registered to the prometheus.DefaultRegisterer.

func NewPromHisto added in v0.0.13

func NewPromHisto(name string) prometheus.Histogram

Create new Histogram.

The created Histogram is automatically registered to the prometheus.DefaultRegisterer.

func NewPromHistoVec added in v0.0.13

func NewPromHistoVec(name string, labels []string) *prometheus.HistogramVec

Create new HistogramVec.

The HistogramVec is automatically registered to the prometheus.DefaultRegisterer.

func NewPutRequest

func NewPutRequest(url string, body io.Reader) (*http.Request, error)

Create PUT request

func OverwriteConf added in v0.0.31

func OverwriteConf(args []string)

Overwrite existing conf using environment and cli args.

func PTimeOp

func PTimeOp(start time.Time, name string)

Run timer for named operation and print result in log

e.g.,

defer PTimeOp(time.Now(), "someOperation")

func ParseBearer added in v0.0.13

func ParseBearer(authorization string) (string, bool)

func ParseLogLevel

func ParseLogLevel(logLevel string) (logrus.Level, bool)

Parse log level

func PerfLogExclPath

func PerfLogExclPath(path string)

Ask PerfMiddleware to stop measuring perf of provided path

func PerfMiddleware

func PerfMiddleware() gin.HandlerFunc

Perf Middleware that calculates how much time each request takes

func PostJobExec added in v0.0.8

func PostJobExec(hook PostJobHook)

Callback triggered after job execution.

Other callbacks will still be executed even if one of them returns error.

Callback will be ignored, if the scheduler is already running.

func PostJson

func PostJson(url string, json string) (*http.Response, error)

Send POST request

func PostServerBootstrapped

func PostServerBootstrapped(callback func(rail Rail) error)

Add listener that is invoked when server is finally bootstrapped

This usually means all server components are started, such as MySQL connection, Redis Connection and so on.

Caller is free to call PostServerBootstrapped inside another PostServerBootstrapped callback.

func PreConfiguredFormatter

func PreConfiguredFormatter() logrus.Formatter

Get pre-configured TextFormatter for logrus

func PreJobExec added in v0.0.8

func PreJobExec(hook PreJobHook)

Callback triggered before job execution.

The job and other callbacks will still be executed even if one of the callback returns error.

Callback will be ignored, if the scheduler is already running.

func PreProcessGin added in v0.0.16

func PreProcessGin(preProcessor GinPreProcessor)

Process *gin.Engine before the web server starts, particularly useful when trying to add middleware.

func PreServerBootstrap

func PreServerBootstrap(callback func(rail Rail) error)

Add listener that is invoked before the server is fully bootstrapped

This usually means that the configuration is loaded, and the logging is configured, but the server components are not yet initialized.

Caller is free to call PostServerBootstrapped or PreServerBootstrap inside another PreServerBootstrap callback.

func PrepareWebStaticFs added in v0.0.29

func PrepareWebStaticFs(fs embed.FS, dir string)

Prepare to serve static files in embedded fs.

Static files are all served by paths with prefix '/static'.

Notice that index.html must be renamed to index.htm or else it won't work.

If you are using Angular framework, you may add extra build param as follows. The idea is still the same for other frameworks.

ng build --baseHref=/static/

func PrometheusBootstrap

func PrometheusBootstrap(rail Rail) error

func PrometheusBootstrapCondition added in v0.0.8

func PrometheusBootstrapCondition(rail Rail) (bool, error)

func PrometheusHandler

func PrometheusHandler() http.Handler

Default handler for prometheus metrics.

func RawAny

func RawAny(url string, handler RawTRouteHandler, extra ...util.StrPair)

Register ANY request route (raw version)

func RegisterBootstrapCallback

func RegisterBootstrapCallback(bootstrapComponent ComponentBootstrap)

Register server component bootstrap callback

When such callback is invoked, configuration should be fully loaded, the callback is free to read the loaded configuration and decide whether or not the server component should be initialized, e.g., by checking if the enable flag is true.

func RegisterConsulService added in v0.0.28

func RegisterConsulService() error

Register current instance as a service

If we have already registered before, current method call will be ignored.

This func looks for following prop:

"server.port"
"consul.registerName"
"consul.healthCheckInterval"
"consul.registerAddress"
"consul.healthCheckUrl"
"consul.healthCheckTimeout"
"consul.healthCheckFailedDeregisterAfter"

func ResolveArg

func ResolveArg(arg string) string

Resolve argument, e.g., for arg like '${someArg}', it will in fact look for 'someArg' in os.Env

func ResolveServerHost

func ResolveServerHost(address string) string

Resolve server host, use IPV4 if the given address is empty or '0.0.0.0'

func ScheduleCron

func ScheduleCron(job Job) error

add a cron job to scheduler, note that the cron expression includes second, e.g., '*/1 * * * * *'

this func doesn't start the scheduler

func SchedulerBootstrap

func SchedulerBootstrap(rail Rail) error

func SendGet

func SendGet(url string, headers map[string][]string) (*http.Response, error)

Send GET request

func SendPost

func SendPost(url string, body io.Reader) (*http.Response, error)

Send POST request

func ServeStatic added in v0.0.29

func ServeStatic(inb *Inbound, fs embed.FS, file string)

func ServeTempl added in v0.0.29

func ServeTempl(inb *Inbound, fs embed.FS, tmplName string, data any)

func SetDefProp

func SetDefProp(prop string, defVal any)

Set default value for the prop

func SetDefaultTimeout added in v0.0.6

func SetDefaultTimeout(ttl time.Duration)

Set default http client timeout

func SetEnv

func SetEnv(key string, val string)

Set environment variable

func SetErrLogHandler added in v0.0.33

func SetErrLogHandler(handler ErrorLogHandler) bool

Setup error log handler.

ErrorLogHnadler is invoked when ERROR level log is printed, the log messages passed to handler are buffered, but handler should never block for a long time (i.e., process as fast as possible). If the buffer is full, latest error log messages are simply dropped.

ErrorLogHandler can only be set once.

func SetLogLevel added in v0.0.8

func SetLogLevel(level string)

func SetProp

func SetProp(prop string, val any)

Set value for the prop

func SetResultBodyBuilder added in v0.0.25

func SetResultBodyBuilder(rbb ResultBodyBuilder) error

Replace the default ResultBodyBuilder

func Shutdown

func Shutdown()

Shutdown server

func SprintMemStats added in v0.0.13

func SprintMemStats(ms runtime.MemStats) string

func StartSchedulerAsync

func StartSchedulerAsync()

Start scheduler asynchronously

func StartSchedulerBlocking

func StartSchedulerBlocking()

Start scheduler and block current routine

func StopScheduler

func StopScheduler()

Stop scheduler

func SubscribeServerChanges added in v0.0.19

func SubscribeServerChanges(rail Rail, name string, cbk func()) error

Subscribe to changes to service instances.

Callback is triggered asynchronously.

func TimeOp

func TimeOp(r Rail, start time.Time, name string)

Run timer for named operation and print result in log

e.g.,

defer TimeOp(ec, time.Now(), "someOperation")

func TraceLogger

func TraceLogger(ctx context.Context) *logrus.Entry

Return logger with tracing infomation

func TraceMiddleware

func TraceMiddleware() gin.HandlerFunc

Tracing Middleware

func TraceRequest

func TraceRequest(ctx context.Context, req *http.Request) *http.Request

Wraper request with tracing key/value pairs on http headers

func Tracef added in v0.0.12

func Tracef(format string, args ...interface{})

func UnmarshalFromProp

func UnmarshalFromProp(ptr any)

Unmarshal configuration.

func UnmarshalFromPropKey added in v0.0.22

func UnmarshalFromPropKey(key string, ptr any)

Unmarshal configuration from a speicific key.

func UsePropagationKeys added in v0.0.25

func UsePropagationKeys(forEach func(key string))

func Validate

func Validate(target any) error

Validate target object based on the validation rules specified by tags 'valid:"[RULE]"'.

Available Rules:

  • maxLen
  • notEmpty
  • notNil
  • positive
  • positiveOrZero
  • negative
  • negativeOrZero
  • notZero
  • validated

func ValidateIntRule

func ValidateIntRule(ival int64, rule string, fname string, param string) error

func ValidateRule

func ValidateRule(field reflect.StructField, value reflect.Value, rule string, ruleParam string) error

func Warn added in v0.0.8

func Warn(args ...interface{})

func Warnf added in v0.0.8

func Warnf(format string, args ...interface{})

func WebServerBootstrap

func WebServerBootstrap(rail Rail) error

func WebServerBootstrapCondition added in v0.0.8

func WebServerBootstrapCondition(rail Rail) (bool, error)

Types

type CTFormatter

type CTFormatter struct {
}

func (*CTFormatter) Format

func (c *CTFormatter) Format(entry *logrus.Entry) ([]byte, error)

type ComponentBootstrap

type ComponentBootstrap struct {
	// name of the component.
	Name string
	// the actual bootstrap function.
	Bootstrap func(rail Rail) error
	// check whether component should be bootstraped
	Condition func(rail Rail) (bool, error)
	// order of which the components are bootstraped, natural order, it's by default 15.
	Order int
}

type ConsulApiImpl added in v0.0.6

type ConsulApiImpl struct{}

func (ConsulApiImpl) CatalogFetchServiceNames added in v0.0.6

func (c ConsulApiImpl) CatalogFetchServiceNames(rail Rail) (map[string][]string, error)

Fetch all registered services, this method always call Consul instead of reading from cache

func (ConsulApiImpl) CatalogFetchServiceNodes added in v0.0.6

func (c ConsulApiImpl) CatalogFetchServiceNodes(rail Rail, name string) ([]*api.CatalogService, error)

Fetch registered service by name, this method always call Consul instead of reading from cache

func (ConsulApiImpl) DeregisterService added in v0.0.6

func (c ConsulApiImpl) DeregisterService(serviceId string) error

func (ConsulApiImpl) RegisterService added in v0.0.12

func (c ConsulApiImpl) RegisterService(registration *api.AgentServiceRegistration) error

type ConsulServerList added in v0.0.28

type ConsulServerList struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

Holder of a list of ServiceHolder

func (*ConsulServerList) IsSubscribed added in v0.0.28

func (s *ConsulServerList) IsSubscribed(rail Rail, service string) bool

func (*ConsulServerList) ListServers added in v0.0.28

func (s *ConsulServerList) ListServers(rail Rail, name string) []Server

func (*ConsulServerList) PollInstance added in v0.0.28

func (s *ConsulServerList) PollInstance(rail Rail, name string) error

Fetch and cache services nodes.

func (*ConsulServerList) PollInstances added in v0.0.28

func (s *ConsulServerList) PollInstances(rail Rail) error

func (*ConsulServerList) Subscribe added in v0.0.28

func (s *ConsulServerList) Subscribe(rail Rail, service string) error

func (*ConsulServerList) Unsubscribe added in v0.0.28

func (s *ConsulServerList) Unsubscribe(rail Rail, service string) error

func (*ConsulServerList) UnsubscribeAll added in v0.0.28

func (s *ConsulServerList) UnsubscribeAll(rail Rail) error

type ErrorLog added in v0.0.33

type ErrorLog struct {
	Time     time.Time
	TraceId  string
	SpanId   string
	FuncName string
	Message  string
}

type ErrorLogHandler added in v0.0.33

type ErrorLogHandler func(el *ErrorLog)

type GetPipelineDocFunc added in v0.1.0

type GetPipelineDocFunc func() []PipelineDoc

type GinPreProcessor added in v0.0.16

type GinPreProcessor func(rail Rail, engine *gin.Engine)

Preprocessor of *gin.Engine.

type GnResp

type GnResp[T any] struct {
	ErrorCode string `json:"errorCode" desc:"error code"`
	Msg       string `json:"msg" desc:"message"`
	Error     bool   `json:"error" desc:"whether the request was successful"`
	Data      T      `json:"data" desc:"response data"`
}

Generic version of Resp

func OkGnResp added in v0.0.25

func OkGnResp[T any](data T) GnResp[T]

func WrapGnResp added in v0.0.25

func WrapGnResp[T any](data T, err error) (GnResp[T], error)

func (GnResp[T]) Err

func (r GnResp[T]) Err() error

func (GnResp[T]) MappedRes added in v0.0.15

func (r GnResp[T]) MappedRes(mapper map[string]error) (T, error)

func (GnResp[T]) Res added in v0.0.3

func (r GnResp[T]) Res() (T, error)

func (GnResp[T]) Unwrap added in v0.0.25

func (r GnResp[T]) Unwrap() Resp

type HardcodedServiceRegistry added in v0.0.14

type HardcodedServiceRegistry struct {
}

Service registry backed by loaded configuration.

func (HardcodedServiceRegistry) ListServers added in v0.0.14

func (r HardcodedServiceRegistry) ListServers(rail Rail, service string) ([]Server, error)

func (HardcodedServiceRegistry) ResolveUrl added in v0.0.14

func (r HardcodedServiceRegistry) ResolveUrl(rail Rail, service string, relativeUrl string) (string, error)

type HealthIndicator added in v0.0.6

type HealthIndicator struct {
	Name        string               // name of the indicator
	CheckHealth func(rail Rail) bool // Check health
}

Indicator of health status

type HealthStatus added in v0.0.6

type HealthStatus struct {
	Name    string
	Healthy bool
}

func CheckHealth added in v0.0.6

func CheckHealth(rail Rail) []HealthStatus

Check health status.

type HistTimer added in v0.0.13

type HistTimer struct {
	// contains filtered or unexported fields
}

Timer based on prometheus.Histogram.

Duration is measured in millisecond.

Use NewHistTimer to create a new one, and each timer can only be used for once.

func NewHistTimer added in v0.0.13

func NewHistTimer(hist prometheus.Histogram) *HistTimer

Create new timer that is backed by a prometheus.Histogram. Each timer can only be used for once.

func (*HistTimer) ObserveDuration added in v0.0.13

func (t *HistTimer) ObserveDuration() time.Duration

func (*HistTimer) Reset added in v0.0.25

func (t *HistTimer) Reset()

type HttpRoute

type HttpRoute struct {
	Url             string
	Method          string
	Extra           map[string][]any
	Desc            string     // description of the route (metadata).
	Scope           string     // the documented access scope of the route, it maybe "PUBLIC" or something else (metadata).
	Resource        string     // the documented resource that the route should be bound to (metadata).
	Headers         []ParamDoc // the documented header parameters that will be used by the endpoint (metadata).
	QueryParams     []ParamDoc // the documented query parameters that will used by the endpoint (metadata).
	JsonRequestVal  any        // the documented json request value that is expected by the endpoint (metadata).
	JsonResponseVal any        // the documented json response value that will be returned by the endpoint (metadata).
}

func GetHttpRoutes

func GetHttpRoutes() []HttpRoute

Get recorded http server routes

type HttpRouteDoc added in v0.0.23

type HttpRouteDoc struct {
	Url              string
	Method           string
	Extra            map[string][]any
	Desc             string     // description of the route (metadata).
	Scope            string     // the documented access scope of the route, it maybe "PUBLIC" or something else (metadata).
	Resource         string     // the documented resource that the route should be bound to (metadata).
	Headers          []ParamDoc // the documented header parameters that will be used by the endpoint (metadata).
	QueryParams      []ParamDoc // the documented query parameters that will used by the endpoint (metadata).
	JsonRequestDesc  []JsonDesc // the documented json request type that is expected by the endpoint (metadata).
	JsonResponseDesc []JsonDesc // the documented json response type that will be returned by the endpoint (metadata).
	Curl             string     // curl demo
	JsonReqTsDef     string     // json request type def in ts
	JsonRespTsDef    string     // json response type def in ts
	NgHttpClientDemo string     // angular http client demo
	MisoTClientDemo  string     // miso TClient demo
}

type Inbound added in v0.0.26

type Inbound struct {
	// contains filtered or unexported fields
}

Inbound request context.

Inbound hides the underlying engine (e.g., *gin.Context) using .Engine() method. In most cases, you should not attempt to cast the engine explictly, it's possible that miso will replace the engine in future release.

However, you should be able to satisfy most of your need by calling .Unwrap(), that returns the underlying http.ResponseWriter, *http.Request.

Use miso.Rail for tracing (not just logs), pass it around your application code and the code calling miso's methods course.

func (*Inbound) AddHeader added in v0.0.26

func (i *Inbound) AddHeader(k string, v string)

func (*Inbound) Engine added in v0.0.26

func (i *Inbound) Engine() any

func (*Inbound) HandleResult added in v0.0.26

func (i *Inbound) HandleResult(result any, err error)

Handle the result using universally configured handler.

The result or error is written back to the client. In most cases, caller must exit the handler after calling this method. Theoritically, this method is only useful for RawGet, RawPut, RawPost, RawDelete. Other methods, such as IGet, IPost, Post, Put or Delete, handle the results automatically in exactly the same way.

E.g.,

miso.RawGet("/dir/info", func(inb *miso.Inbound) {
	// ... do something

	if err != nil {
		inb.HandleResult(nil, err) // something goes wrong
		return
	}

	// return result back to the client
	inb.HandleResult(result, err)
})

func (*Inbound) Header added in v0.0.26

func (i *Inbound) Header(k string) string

func (*Inbound) Query added in v0.0.26

func (i *Inbound) Query(k string) string

func (*Inbound) Rail added in v0.0.26

func (i *Inbound) Rail() Rail

func (*Inbound) SetHeader added in v0.0.26

func (i *Inbound) SetHeader(k string, v string)

func (*Inbound) Status added in v0.0.26

func (i *Inbound) Status(status int)

func (*Inbound) Unwrap added in v0.0.26

func (i *Inbound) Unwrap() (http.ResponseWriter, *http.Request)

type Job added in v0.0.8

type Job struct {
	Name                   string           // name of the job.
	Cron                   string           // cron expr.
	CronWithSeconds        bool             // whether cron expr contains the second field.
	Run                    func(Rail) error // actual job execution logic.
	LogJobExec             bool             // whether job execution should be logged, error msg is always logged and is not affected by this option.
	TriggeredOnBoostrapped bool             // whether job should be triggered when server is fully bootstrapped
}

type JobExecStats added in v0.0.8

type JobExecStats struct {
	Time time.Duration
	Err  error
}

type JobInf added in v0.0.8

type JobInf struct {
	Name            string
	Cron            string
	CronWithSeconds bool
}

type JsonDesc added in v0.1.0

type JsonDesc struct {
	FieldName string
	Name      string
	TypeName  string
	Desc      string
	Fields    []JsonDesc
}

func BuildJsonDesc added in v0.1.0

func BuildJsonDesc(v reflect.Value) []JsonDesc

type LazyRouteDecl added in v0.0.23

type LazyRouteDecl struct {
	Url     string
	Method  string
	Handler func(c *gin.Context)

	RegisterFunc func(extra ...util.StrPair)
	Extras       []util.StrPair
}

Lazy route declaration

func Delete

func Delete[Res any](url string, handler TRouteHandler[Res]) *LazyRouteDecl

Register DELETE request.

The result and error are automatically wrapped to miso.Resp (see miso.SetResultBodyBuilder func) and serialized to json.

func Get

func Get[Res any](url string, handler TRouteHandler[Res]) *LazyRouteDecl

Register GET request.

The result and error are automatically wrapped to miso.Resp (see miso.SetResultBodyBuilder func) and serialized to json.

func IDelete

func IDelete[Req any, Res any](url string, handler MappedTRouteHandler[Req, Res]) *LazyRouteDecl

Register DELETE request.

Req type should be a struct, where all fields are automatically mapped from the request using 'json' tag or 'form' tag (for form-data, query param) or 'header' tag (only supports string/*string).

Res type should be a struct. By default both Res value and error (if not nil) will be wrapped inside miso.Resp and serialized to json. Wrapping to miso.Resp is customizable using miso.SetResultBodyBuilder func.

With both Req and Res type declared, miso will automatically parse these two types using reflect and generate an API documentation describing the endpoint.

func IGet

func IGet[Req any, Res any](url string, handler MappedTRouteHandler[Req, Res]) *LazyRouteDecl

Register GET request.

Req type should be a struct, where all fields are automatically mapped from the request using 'form' tag (for form-data, query param) or 'header' tag (only supports string/*string).

Res type should be a struct. By default both Res value and error (if not nil) will be wrapped inside miso.Resp and serialized to json. Wrapping to miso.Resp is customizable using miso.SetResultBodyBuilder func.

With both Req and Res type declared, miso will automatically parse these two types using reflect and generate an API documentation describing the endpoint.

func IPost

func IPost[Req any, Res any](url string, handler MappedTRouteHandler[Req, Res]) *LazyRouteDecl

Register POST request.

Req type should be a struct, where all fields are automatically mapped from the request using 'json' tag or 'form' tag (for form-data, query param) or 'header' tag (only supports string/*string).

Res type should be a struct. By default both Res value and error (if not nil) will be wrapped inside miso.Resp and serialized to json. Wrapping to miso.Resp is customizable using miso.SetResultBodyBuilder func.

With both Req and Res type declared, miso will automatically parse these two types using reflect and generate an API documentation describing the endpoint.

func IPut

func IPut[Req any, Res any](url string, handler MappedTRouteHandler[Req, Res]) *LazyRouteDecl

Register PUT request.

Req type should be a struct, where all fields are automatically mapped from the request using 'json' tag or 'form' tag (for form-data, query param) or 'header' tag (only supports string/*string).

Res type should be a struct. By default both Res value and error (if not nil) will be wrapped inside miso.Resp and serialized to json. Wrapping to miso.Resp is customizable using miso.SetResultBodyBuilder func.

With both Req and Res type declared, miso will automatically parse these two types using reflect and generate an API documentation describing the endpoint.

func NewLazyRouteDecl added in v0.0.23

func NewLazyRouteDecl(url string, method string, handler func(c *gin.Context)) *LazyRouteDecl

func Post

func Post[Res any](url string, handler TRouteHandler[Res]) *LazyRouteDecl

Register POST request.

The result and error are automatically wrapped to miso.Resp (see miso.SetResultBodyBuilder func) and serialized to json.

func Put

func Put[Res any](url string, handler TRouteHandler[Res]) *LazyRouteDecl

Register PUT request.

The result and error are automatically wrapped to miso.Resp (see miso.SetResultBodyBuilder func) and serialized to json.

func RawDelete

func RawDelete(url string, handler RawTRouteHandler) *LazyRouteDecl

Register DELETE request route (raw version)

func RawGet

func RawGet(url string, handler RawTRouteHandler) *LazyRouteDecl

Register GET request route (raw version)

func RawPost

func RawPost(url string, handler RawTRouteHandler) *LazyRouteDecl

Register POST request route (raw version)

func RawPut

func RawPut(url string, handler RawTRouteHandler) *LazyRouteDecl

Register PUT request route (raw version)

func (*LazyRouteDecl) Desc added in v0.0.23

func (g *LazyRouteDecl) Desc(desc string) *LazyRouteDecl

Add endpoint description (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) DocHeader added in v0.0.23

func (g *LazyRouteDecl) DocHeader(headerName string, desc string) *LazyRouteDecl

Document header parameter that the endpoint will use (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) DocHeaderReq added in v0.0.26

func (g *LazyRouteDecl) DocHeaderReq(v any) *LazyRouteDecl

Document header parameters that the endpoint expects (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) DocJsonReq added in v0.0.23

func (g *LazyRouteDecl) DocJsonReq(v any) *LazyRouteDecl

Document json request that the endpoint expects (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) DocJsonResp added in v0.0.23

func (g *LazyRouteDecl) DocJsonResp(v any) *LazyRouteDecl

Document json response that the endpoint returns (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) DocQueryParam added in v0.0.23

func (g *LazyRouteDecl) DocQueryParam(queryName string, desc string) *LazyRouteDecl

Document query parameter that the endpoint will use (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) DocQueryReq added in v0.0.25

func (g *LazyRouteDecl) DocQueryReq(v any) *LazyRouteDecl

Document query parameters that the endpoint expects (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) Extra added in v0.0.23

func (g *LazyRouteDecl) Extra(key string, value any) *LazyRouteDecl

Add extra info to endpoint's metadata.

func (*LazyRouteDecl) Prepend added in v0.0.23

func (g *LazyRouteDecl) Prepend(baseUrl string)

func (*LazyRouteDecl) Protected added in v0.0.23

func (g *LazyRouteDecl) Protected() *LazyRouteDecl

Documents that the endpoint requires protection (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) Public added in v0.0.23

func (g *LazyRouteDecl) Public() *LazyRouteDecl

Mark endpoint publicly accessible (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) Resource added in v0.0.23

func (g *LazyRouteDecl) Resource(resource string) *LazyRouteDecl

Record the resource that the endppoint should be bound to (only serves as metadata that maybe used by some plugins).

func (*LazyRouteDecl) Scope added in v0.1.4

func (g *LazyRouteDecl) Scope(scope string) *LazyRouteDecl

Document the access scope of the endpoint (only serves as metadata that maybe used by some plugins).

type LocalCache

type LocalCache[T any] map[string]T

Simple local map-based cache.

This should not be a long-live object.

func NewLocalCache

func NewLocalCache[T any]() LocalCache[T]

create new LocalCache with key of type string and value of type T.

func (LocalCache[T]) Get

func (lc LocalCache[T]) Get(key string, supplier func(string) (T, error)) (T, error)

get cached value identified by the key, if absent, call the supplier func instead, and cache and return the supplied value.

type MappedTRouteHandler

type MappedTRouteHandler[Req any, Res any] func(inb *Inbound, req Req) (Res, error)

Traced and parameters mapped route handler.

Req type should be a struct, where all fields are automatically mapped from the request using 'json' tag or 'form' tag (for form-data, query param) or 'header' tag (only supports string/*string).

Res type should be a struct. By default both Res value and error (if not nil) will be wrapped inside miso.Resp and serialized to json. Wrapping to miso.Resp is customizable using miso.SetResultBodyBuilder func.

With both Req and Res type declared, miso will automatically parse these two types using reflect and generate an API documentation describing the endpoint.

type MetricsCollector added in v0.0.13

type MetricsCollector struct {
	Desc      []metrics.Description
	Samples   []metrics.Sample
	SampleMap map[string]*metrics.Sample
	// contains filtered or unexported fields
}

Collector of runtime/metrics.

Use NewMetricsCollector() to create a new collector, the collector is thread-safe. Periodically call Read() to load metrics from runtime. Once the metrics are loaded, you can either use Value() or MemStats() func to access the values that you are interested in.

func NewMetricsCollector added in v0.0.13

func NewMetricsCollector(descs []metrics.Description) MetricsCollector

Create new MetricsCollector.

MetricsCollector only supports Uint64 metrics, those that are not Uint64 kind, are simply ignored.

func (*MetricsCollector) MemStats added in v0.0.13

func (m *MetricsCollector) MemStats() runtime.MemStats

func (*MetricsCollector) Read added in v0.0.13

func (m *MetricsCollector) Read()

func (*MetricsCollector) Value added in v0.0.13

func (m *MetricsCollector) Value(name string) uint64

type MisoErr added in v0.0.3

type MisoErr struct {
	Code        string // error code.
	Msg         string // error message returned to the client requested to the endpoint.
	InternalMsg string // internal message that is only logged on server.
}

Miso Error.

Use NewErrf(...) to instantiate.
var (
	// Unknown Error
	ErrUnknownError *MisoErr = NewErrf("Unknown Error")

	// Not Permitted
	ErrNotPermitted *MisoErr = NewErrf("Not Permitted")
)
var (
	// Error that represents None or Nil.
	//
	// Use miso.IsNoneErr(err) to check if an error represents None.
	NoneErr *MisoErr = NewErrf("none")
)

func NewErrf added in v0.0.22

func NewErrf(msg string, args ...any) *MisoErr

Create new MisoErr with message.

func (*MisoErr) Error added in v0.0.3

func (e *MisoErr) Error() string

func (*MisoErr) HasCode added in v0.0.6

func (e *MisoErr) HasCode() bool

func (*MisoErr) Is added in v0.0.25

func (e *MisoErr) Is(target error) bool

Implements *MisoErr Is check.

Returns true, if both are *MisoErr and the code matches.

WithInternalMsg always create new error, so we can basically reuse the same error created using 'miso.NewErrf(...).WithCode(...)'

var ErrIllegalArgument = miso.NewErrf(...).WithCode(...)

var e1 = ErrIllegalArgument.WithInternalMsg(...)
var e2 = ErrIllegalArgument.WithInternalMsg(...)

errors.Is(e1, ErrIllegalArgument)
errors.Is(e2, ErrIllegalArgument)

func (*MisoErr) WithCode added in v0.0.22

func (e *MisoErr) WithCode(code string) *MisoErr

func (*MisoErr) WithInternalMsg added in v0.0.22

func (e *MisoErr) WithInternalMsg(msg string, args ...any) *MisoErr

type NewRollingLogFileParam

type NewRollingLogFileParam struct {
	Filename   string // filename
	MaxSize    int    // max file size in mb
	MaxAge     int    // max age in day
	MaxBackups int    // max number of files
}

type OrderedShutdownHook added in v0.0.23

type OrderedShutdownHook struct {
	Hook  func()
	Order int
}

type PageRes

type PageRes[T any] struct {
	Page    Paging `json:"paging" desc:"pagination parameters"`
	Payload []T    `json:"payload" desc:"payload values in current page"`
}

type Paging

type Paging struct {
	Limit int `json:"limit" desc:"page limit"`
	Page  int `json:"page" desc:"page number, 1-based"`
	Total int `json:"total" desc:"total count"`
}

func RespPage

func RespPage(reqPage Paging, total int) Paging

Build Paging for response

func (Paging) GetLimit

func (p Paging) GetLimit() int

func (Paging) GetOffset

func (p Paging) GetOffset() int

func (Paging) GetPage

func (p Paging) GetPage() int

func (Paging) ToRespPage

func (p Paging) ToRespPage(total int) Paging

type ParamDoc added in v0.0.22

type ParamDoc struct {
	Name string
	Desc string
}

type PipelineDoc added in v0.0.33

type PipelineDoc struct {
	Name        string
	Desc        string
	Exchange    string
	RoutingKey  string
	Queue       string
	PayloadDesc []JsonDesc
}

type PostJobHook added in v0.0.8

type PostJobHook func(rail Rail, inf JobInf, stats JobExecStats) error

Hook triggered after job's execution.

type PreJobHook added in v0.0.8

type PreJobHook func(rail Rail, inf JobInf) error

Hook triggered before job's execution.

type PropagationKeys

type PropagationKeys struct {
	// contains filtered or unexported fields
}

type Rail

type Rail struct {
	// contains filtered or unexported fields
}

Rail, an object that carries trace infromation along with the execution.

func BuildRail

func BuildRail(c *gin.Context) Rail

Build Rail from gin.Context.

This func creates new Rail for the first time by setting up proper traceId and spanId.

It can also recognize that a traceId (and spanId) was previously created, and do attempt to reuse these tracing values, such that the Rail acts as if it's the previous one, this is especially useful when we are recovering from a panic. In most cases, we should only call BuildRail for once.

However, if the Rail has attempted to overwrite it's spanId (i.e., creating new span), this newly created spanId will not be reflected on the Rail created here. But this should be fine, because new span is usually created for async operation.

func EmptyRail

func EmptyRail() Rail

Create empty Rail.

func NewRail

func NewRail(ctx context.Context) Rail

Create new Rail from context.

func (Rail) Context added in v0.0.23

func (r Rail) Context() context.Context

func (Rail) CtxValInt

func (r Rail) CtxValInt(key string) int

func (Rail) CtxValStr

func (r Rail) CtxValStr(key string) string

func (Rail) CtxValue

func (r Rail) CtxValue(key string) any

func (Rail) Debug

func (r Rail) Debug(args ...interface{})

func (Rail) Debugf

func (r Rail) Debugf(format string, args ...interface{})

func (Rail) Debugln added in v0.0.28

func (r Rail) Debugln(args ...interface{})

func (Rail) Error

func (r Rail) Error(args ...interface{})

func (Rail) Errorf

func (r Rail) Errorf(format string, args ...interface{})

func (Rail) Errorln added in v0.0.28

func (r Rail) Errorln(args ...interface{})

func (Rail) Fatal

func (r Rail) Fatal(args ...interface{})

func (Rail) Fatalf

func (r Rail) Fatalf(format string, args ...interface{})

func (Rail) Fatalln added in v0.0.28

func (r Rail) Fatalln(args ...interface{})

func (Rail) Info

func (r Rail) Info(args ...interface{})

func (Rail) Infof

func (r Rail) Infof(format string, args ...interface{})

func (Rail) Infoln added in v0.0.28

func (r Rail) Infoln(args ...interface{})

func (Rail) IsDone added in v0.1.4

func (r Rail) IsDone() bool

func (Rail) NextSpan

func (r Rail) NextSpan() Rail

Create a new Rail with a new SpanId

func (Rail) Panic added in v0.0.28

func (r Rail) Panic(args ...interface{})

func (Rail) Panicf added in v0.0.28

func (r Rail) Panicf(format string, args ...interface{})

func (Rail) Panicln added in v0.0.28

func (r Rail) Panicln(args ...interface{})

func (Rail) Print added in v0.0.28

func (r Rail) Print(args ...interface{})

func (Rail) Printf added in v0.0.28

func (r Rail) Printf(format string, args ...interface{})

func (Rail) Println added in v0.0.28

func (r Rail) Println(args ...interface{})

func (Rail) SpanId

func (r Rail) SpanId() string

func (Rail) TraceId

func (r Rail) TraceId() string

func (Rail) Tracef added in v0.0.12

func (r Rail) Tracef(format string, args ...interface{})

func (Rail) Warn

func (r Rail) Warn(args ...interface{})

func (Rail) Warnf

func (r Rail) Warnf(format string, args ...interface{})

func (Rail) Warnln added in v0.0.28

func (r Rail) Warnln(args ...interface{})

func (Rail) WithCancel

func (r Rail) WithCancel() (Rail, context.CancelFunc)

Create new Rail with context's CancelFunc

func (Rail) WithCtxVal

func (r Rail) WithCtxVal(key string, val any) Rail

type RawTRouteHandler

type RawTRouteHandler func(inb *Inbound)

Raw version of traced route handler.

type Resp

type Resp struct {
	ErrorCode string      `json:"errorCode" desc:"error code"`
	Msg       string      `json:"msg" desc:"message"`
	Error     bool        `json:"error" desc:"whether the request was successful"`
	Data      interface{} `json:"data" desc:"response data"`
}

Web Endpoint's Resp

func ErrorResp

func ErrorResp(msg string) Resp

Build error Resp

func ErrorRespWCode

func ErrorRespWCode(code string, msg string) Resp

Build error Resp

func OkResp

func OkResp() Resp

Build OK Resp

func OkRespWData

func OkRespWData(data interface{}) Resp

Build OK Resp with data

func WrapResp

func WrapResp(rail Rail, data interface{}, err error, url string) Resp

Wrap result (data and err) with a common Resp object.

If err is not nil, returns a Resp body containing the error code and message. If err is nil, the data is wrapped inside a Resp object and returned with http.StatusOK.

type RespUnwrapper added in v0.0.25

type RespUnwrapper interface {
	Unwrap() Resp
}

type ResultBodyBuilder added in v0.0.8

type ResultBodyBuilder struct {
	// wrap error in json, the returned object will be serialized to json.
	ErrJsonBuilder func(rail Rail, url string, err error) any

	// wrap payload object, the returned object will be serialized to json.
	PayloadJsonBuilder func(payload any) any

	// build empty ok response object, the returned object will be serialized to json.
	OkJsonBuilder func() any
}

type RoutingGroup added in v0.0.4

type RoutingGroup struct {
	Base  string
	Paths []TreePath
}

func BaseRoute added in v0.0.4

func BaseRoute(baseUrl string) *RoutingGroup

Group routes together to share the same base url.

func GroupRoute added in v0.0.23

func GroupRoute(baseUrl string, grouped ...TreePath) *RoutingGroup

Group routes together to share the same base url.

func (*RoutingGroup) Group added in v0.0.4

func (rg *RoutingGroup) Group(grouped ...TreePath) *RoutingGroup

Group routes, routes are immediately registered

func (*RoutingGroup) Prepend added in v0.0.23

func (rg *RoutingGroup) Prepend(baseUrl string)

type Server added in v0.0.14

type Server struct {
	Protocol string
	Address  string
	Port     int
	Meta     map[string]string
}

func SelectAnyServer added in v0.0.22

func SelectAnyServer(rail Rail, name string) (Server, error)

Select one Server randomly.

This func internally calls SelectServer with RandomServerSelector.

func SelectServer added in v0.0.14

func SelectServer(rail Rail, name string, selector func(servers []Server) int) (Server, error)

Select one Server based on the provided selector.

GetServerList() is internally called to obtain current ServerList implementation.

If none is found and the service is not subscribed yet in the ServerList, this func subscribes to the service and polls the service instances immediately.

If ServerList indeed doesn't find any available instance for the service, ErrServiceInstanceNotFound is returned.

func (*Server) BuildUrl added in v0.0.14

func (c *Server) BuildUrl(relUrl string) string

Build the complete request url.

func (*Server) ServerAddress added in v0.0.14

func (c *Server) ServerAddress() string

Build server address with host and port concatenated, e.g., 'localhost:8080'

type ServerChangeListenerMap added in v0.0.19

type ServerChangeListenerMap struct {
	Listeners map[string][]func()
	Pool      *util.AsyncPool
	sync.RWMutex
}

func (*ServerChangeListenerMap) SubscribeChange added in v0.0.28

func (s *ServerChangeListenerMap) SubscribeChange(name string, cbk func())

func (*ServerChangeListenerMap) TriggerListeners added in v0.0.28

func (s *ServerChangeListenerMap) TriggerListeners(name string)

type ServerList added in v0.0.14

type ServerList interface {
	PollInstances(rail Rail) error
	PollInstance(rail Rail, name string) error
	ListServers(rail Rail, name string) []Server
	IsSubscribed(rail Rail, service string) bool
	Subscribe(rail Rail, service string) error
	Unsubscribe(rail Rail, service string) error
	UnsubscribeAll(rail Rail) error
}

type ServerListServiceRegistry added in v0.0.28

type ServerListServiceRegistry struct {
	Rule ServerSelector
}

func (ServerListServiceRegistry) ListServers added in v0.0.28

func (c ServerListServiceRegistry) ListServers(rail Rail, service string) ([]Server, error)

func (ServerListServiceRegistry) ResolveUrl added in v0.0.28

func (c ServerListServiceRegistry) ResolveUrl(rail Rail, service string, relativeUrl string) (string, error)

type ServerSelector added in v0.0.14

type ServerSelector func(servers []Server) int

Server selector, returns index of the selected one.

type ServiceRegistry

type ServiceRegistry interface {
	ResolveUrl(rail Rail, service string, relativeUrl string) (string, error)
	ListServers(rail Rail, service string) ([]Server, error)
}

func GetServiceRegistry

func GetServiceRegistry() ServiceRegistry

Get service registry.

Service registry initialization is lazy, don't store the retunred value in global var.

type TBucket added in v0.0.22

type TBucket[T any] struct {
	// contains filtered or unexported fields
}

func NewTBucket added in v0.0.22

func NewTBucket[T any](val T) TBucket[T]

type TClient

type TClient struct {
	Url        string              // request url (absolute or relative)
	Headers    map[string][]string // request headers
	Ctx        context.Context     // context provided by caller
	QueryParam map[string][]string // query parameters
	Rail       Rail                // rail
	// contains filtered or unexported fields
}

Helper type for sending HTTP requests

Provides convenients methods to build requests, use http.Client and propagate tracing information

func NewDynTClient

func NewDynTClient(ec Rail, relUrl string, serviceName string) *TClient

Create new defualt TClient with EnableServiceDiscovery(), EnableTracing(), and Require2xx() turned on.

The provided relUrl should be a relative url starting with '/'.

func NewTClient

func NewTClient(rail Rail, url string) *TClient

Create new TClient.

func (*TClient) AddHeader

func (t *TClient) AddHeader(k string, v string) *TClient

Append header, subsequent method calls doesn't override previously appended headers

func (*TClient) AddHeaders

func (t *TClient) AddHeaders(headers map[string]string) *TClient

Append headers, subsequent method calls doesn't override previously appended headers

func (*TClient) AddQueryParams

func (t *TClient) AddQueryParams(k string, v ...string) *TClient

Append Query Parameters, subsequent method calls doesn't override previously appended parameters

func (*TClient) Delete

func (t *TClient) Delete() *TResponse

Send DELETE request

func (*TClient) EnableServiceDiscovery

func (t *TClient) EnableServiceDiscovery(serviceName string) *TClient

Enable service discovery

func (*TClient) EnableTracing

func (t *TClient) EnableTracing() *TClient

Enable tracing by putting propagation key/value pairs on http headers.

func (*TClient) Get

func (t *TClient) Get() *TResponse

Send GET request

func (*TClient) Head

func (t *TClient) Head() *TResponse

Send HEAD request

func (*TClient) Http added in v0.0.5

func (t *TClient) Http() *TClient

Append 'http://' protocol.

If service discovery is enabled, or the url contains http protocol already, this will be skipped.

func (*TClient) Https added in v0.0.5

func (t *TClient) Https() *TClient

Append 'https://' protocol.

If service discovery is enabled, or the url contains http protocol already, this will be skipped.

func (*TClient) Options

func (t *TClient) Options() *TResponse

Send OPTIONS request

func (*TClient) Post

func (t *TClient) Post(body io.Reader) *TResponse

Send POST request with reader to request body.

func (*TClient) PostBytes added in v0.0.22

func (t *TClient) PostBytes(body []byte) *TResponse

Send POST request with bytes.

func (*TClient) PostForm

func (t *TClient) PostForm(data url.Values) *TResponse

Send POST request with urlencoded form data

func (*TClient) PostJson

func (t *TClient) PostJson(body any) *TResponse

Send POST request with JSON.

Use simple types like struct instad of pointer for body.

func (*TClient) Put

func (t *TClient) Put(body io.Reader) *TResponse

Send PUT request

func (*TClient) PutBytes added in v0.0.22

func (t *TClient) PutBytes(body []byte) *TResponse

Send PUT request with bytes.

func (*TClient) PutJson

func (t *TClient) PutJson(body any) *TResponse

Send PUT request with JSON

func (*TClient) Require2xx added in v0.0.8

func (t *TClient) Require2xx() *TClient

Requires response to have 2xx status code, if not, the *TResponse will contain error built for this specific reason.

func (*TClient) SetContentType

func (t *TClient) SetContentType(ct string) *TClient

Set Content-Type

func (*TClient) SetHeaders

func (t *TClient) SetHeaders(k string, v ...string) *TClient

Overwrite header

func (*TClient) UseClient added in v0.0.8

func (t *TClient) UseClient(client *http.Client) *TClient

Change the underlying *http.Client

type TResponse

type TResponse struct {
	Rail       Rail
	Ctx        context.Context
	Resp       *http.Response
	RespHeader http.Header
	StatusCode int
	Err        error
}

Helper type for handling HTTP responses

func (*TResponse) Bytes added in v0.0.3

func (tr *TResponse) Bytes() ([]byte, error)

Read response as []bytes.

Response is always closed automatically.

If response body is somehow empty, *miso.NoneErr is returned.

func (*TResponse) Close

func (tr *TResponse) Close() error

Close Response

func (*TResponse) Is2xx

func (tr *TResponse) Is2xx() bool

Is status code 2xx

func (*TResponse) Json added in v0.0.3

func (tr *TResponse) Json(ptr any) error

Read response as JSON object.

Response is always closed automatically.

If response body is somehow empty, *miso.NoneErr is returned.

func (*TResponse) Require2xx

func (tr *TResponse) Require2xx() error

Check if it's 2xx, else return error

func (*TResponse) Str added in v0.0.3

func (tr *TResponse) Str() (string, error)

Read response as string.

Response is always closed automatically.

If response body is somehow empty, *miso.NoneErr is returned.

func (*TResponse) WriteTo added in v0.0.15

func (tr *TResponse) WriteTo(writer io.Writer) (int64, error)

Write the response data to the given writer.

Response is always closed automatically.

If response body is somehow empty, *miso.NoneErr is returned.

type TRouteHandler

type TRouteHandler[Res any] func(inb *Inbound) (Res, error)

Traced route handler.

Res type should be a struct. By default both Res value and error (if not nil) will be wrapped inside miso.Resp and serialized to json. Wrapping to miso.Resp is customizable using miso.SetResultBodyBuilder func.

With Res type declared, miso will automatically parse the Res type using reflect and generate an API documentation describing the endpoint.

type TTLCache added in v0.0.3

type TTLCache[T any] interface {
	TryGet(key string) (T, bool)
	Get(key string, elseGet func() (T, bool)) (T, bool)
	Put(key string, t T)
	Del(key string)
	Size() int
	Exists(key string) bool
	PutIfAbsent(key string, t T) bool

	// Register callback to be invoked when entry is evicted.
	//
	// Callback may be invoked with locks obtained, callback should not block currnet goroutine.
	// Callback should not call any method on TTLCache, deadlock is almost guaranteed.
	OnEvicted(f func(key string, t T))
	Keys() []string
}

Time-based Cache.

func NewTTLCache added in v0.0.3

func NewTTLCache[T any](ttl time.Duration, maxSize int) TTLCache[T]

Create new TTLCache.

Each k/v is associated with a timestamp. Each time a key lookup occurs, it checks whether the k/v is still valid by comparing the timestamp with time.Now().

If the k/v is no longer 'alive', or the cache doesn't have the key, supplier func for the value is called, and the returned value is then cached. I.e., each k/v is evicted only at key lookup, there is no secret go-routine running to do the clean-up, the overhead for maintaining the cache is relatively small.

For the max size, TTLCache will try it's best to maintain it, but it's quite possible that all values in the cache are 'alive'. Whenever the max size is violated, the cache will simply drop the 'least recently put' item.

The returned TTLCache can be used concurrently.

type TickRunner added in v0.0.14

type TickRunner struct {
	// contains filtered or unexported fields
}

Runner that triggers run on every tick.

Create TickRunner using func NewTickRunner(...).

func NewTickRuner added in v0.0.14

func NewTickRuner(freq time.Duration, run func()) *TickRunner

func (*TickRunner) Start added in v0.0.14

func (t *TickRunner) Start()

func (*TickRunner) Stop added in v0.0.14

func (t *TickRunner) Stop()

type TreePath added in v0.0.23

type TreePath interface {
	Prepend(baseUrl string)
}

type ValidationError

type ValidationError struct {
	Field         string
	Rule          string
	ValidationMsg string
}

Validation Error

func (*ValidationError) Error

func (ve *ValidationError) Error() string

type VecTimer added in v0.0.13

type VecTimer struct {
	// contains filtered or unexported fields
}

Timer based on prometheus.HistogramVec.

Duration is measured in millisecond.

Use NewVecTimer to create a new one, and each timer can only be used for once.

func NewVecTimer added in v0.0.13

func NewVecTimer(vec *prometheus.HistogramVec) *VecTimer

Create new timer that is back by prometheus HistogramVec. Each timer can only be used for once.

func (*VecTimer) ObserveDuration added in v0.0.13

func (t *VecTimer) ObserveDuration(labels ...string) time.Duration

func (*VecTimer) Reset added in v0.0.25

func (t *VecTimer) Reset()

Jump to

Keyboard shortcuts

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