golib

package module
v0.0.25 Latest Latest
Warning

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

Go to latest
Published: Apr 8, 2020 License: MIT Imports: 36 Imported by: 66

README

golib

Useful helper types and functions for Go (Golang).

Documentation

Index

Constants

View Source
const (
	// FlagsAll makes RegisterFlags() enable all available flags.
	FlagsAll = 0xffffffff

	// FlagsLog enables flags that configure the logger (Package github.com/sirupsen/logrus).
	FlagsLog = 1 << iota

	// FlagsProfile enables flags the configure profiling of CPU and memory.
	FlagsProfile

	// FlagsTasks enables flags that help debugging the shutdown sequence Tasks and TaskGroups.
	FlagsTasks
)
View Source
const (
	EntrySeparator          = ","
	EntrySeparatorFormatted = EntrySeparator + " "
	ValueSeparator          = "="
)
View Source
const SafeTimeLayout = "2006-01-02_15-04-05"
View Source
const SimpleTimeLayout = "2006-01-02 15:04:05"

Variables

View Source
var (
	// TaskStopTimeout is used by PrintWaitAndStop() to timeout the shutdown sequence,
	// dump all running goroutines and exiting when shutting down takes too long.
	TaskStopTimeout = time.Duration(0)

	// PrintTaskStopWait causes various parts of the TaskGroup functionality to print
	// debug messages when stopping tasks and waiting for them to finish.
	PrintTaskStopWait = false

	// PanicOnTaskTimeout controls, whether the WaitAndStop() method of TaskGroup
	// generates a panic in case of a timeout.
	PanicOnTaskTimeout = true
)
View Source
var (
	// LogFile can be set to non-empty to make ConfigureLogging output all log
	// entries in addition to showing them on the standard error stream.
	// All entries are output to the file, regardless of the log-level configured for the
	// console output.
	LogFile string

	// LogVerbose makes the ConfigureLogging() function set the global log level to Debug.
	LogVerbose bool

	// LogQuiet makes the ConfigureLogging() function set the global log level to Warn, but
	// only of LogVerbose is not set.
	LogQuiet bool

	// LogVeryQuiet makes the ConfigureLogging() function set the global log level to Error,
	// but only if LogVerbose and LogQuiet are both not set.
	LogVeryQuiet bool

	// Log is the package-wide logger for the golib package. It can be configured or disabled.
	Log = log.New()
)
View Source
var (
	// CpuProfileFile will be used to output a CPU profile of the running program,
	// if ProfileCpu() is called. This field is configured by the '-profile-cpu' flag
	// created by RegisterProfileFlags().
	CpuProfileFile = ""

	// MemProfileFile will be used to output a memory usage profile of the running program,
	// if ProfileCpu() is called. This field is configured by the '-profile-mem' flag
	// created by RegisterProfileFlags().
	MemProfileFile = ""
)
View Source
var DefaultGinLogHandler = &GinLogHandler{Logger: Log}
View Source
var DefaultUdpPacketSize = 2048
View Source
var StopLoopTask = errors.New("Stop the LoopTask")

StopLoopTask can be returned from the LoopTask.Loop function to make the loop task stop without reporting an error.

Functions

func Checkerr

func Checkerr(err error)

Checkerr stops the process with a non-zero exit status, if the given error is non-nil. Before exiting, it executes the ErrorExitHook function, if it is defined.

func ConfigureLogger added in v0.0.4

func ConfigureLogger(l *log.Logger)

ConfigureLogger configures the given logger based on Log* variables defined in the package.

func ConfigureLogging

func ConfigureLogging()

ConfigureLogging configures the logger based on the global Log* variables defined in the package. It calls ConfigureLogger() for the standard Logrus logger and the logger of this package. This function should be called early in every main() function, preferably before any prior logging output, but after calling RegisterLogFlags() and flag.Parse().

func DumpGoroutineStacks

func DumpGoroutineStacks()

func EqualStrings

func EqualStrings(a, b []string) bool

func EscapeExistingFlags added in v0.0.5

func EscapeExistingFlags(prefix string)

EscapeExistingFlags can be used before defining new flags to escape existing flags that have been defined by other packages or modules. This can be used to avoid collisions of flag names.

func FindMatchingFiles

func FindMatchingFiles(regex *regexp.Regexp, directories []string) (result []string, errs []error)

FindPrefixedFiles reads the contents of all given directories and returns a list of files with a basename that matches the given regex. It is intended to find plugin executables. All directories are processed, and a list of all encountered errors is returned.

func FirstIpAddress

func FirstIpAddress() (net.IP, error)

FirstIpAddress tries to get the main public IP of the local host. It iterates all available, enabled network interfaces and looks for the first non-local IP address.

func FormatMap

func FormatMap(m map[string]string) string

FormatMap returns a readable representation of the given string map.

func FormatOrderedMap

func FormatOrderedMap(keys []string, values []string) string

FormatOrderedMap returns a readable representation of the given key-value pairs.

func FormatSortedMap added in v0.0.25

func FormatSortedMap(m map[string]string) string

FormatSortedMap returns a readable representation of the given key-value pairs, sorted by the keys.

func FormatStringSlice added in v0.0.23

func FormatStringSlice(stringSlice []string) string

FormatStringSlice formats the given slice of strings to a human-readable string

func InitGin

func InitGin()

func IsExecutable

func IsExecutable(filename string) bool

IsExecutable returns true, if the given file is a regular file with the executable flag enabled.

func LogGinRequests

func LogGinRequests(filename string, logBody, logHeaders bool) gin.HandlerFunc

func NewGinEngine

func NewGinEngine() *gin.Engine

func NewGinEngineWithHandler added in v0.0.8

func NewGinEngineWithHandler(logHandler *GinLogHandler) *gin.Engine

func ParseFlags added in v0.0.5

func ParseFlags() (*flag.FlagSet, []string)

When packages or modules are loaded AFTER parsing flags, avoid collisions when flags are re-defined. The original FlagSet is returned, so that PrintDefaults() can be used. All non-flag arguments are returned as well.

func ParseHashbangArgs

func ParseHashbangArgs(argsPtr *[]string) int

ParseHashbangArgs checks, if the current process was started in one of the following forms:

/path/to/EXECUTABLE executable-script-file <additional args>...
EXECUTABLE "-flag1 -flag2 arg1 arg2" executable-script-file <additional args>...

These forms are used by the OS when running an executable script that has a first line like one of the following:

#!/usr/bin/env EXECUTABLE
#!/path/to/EXECUTABLE -flag1 -flag2 arg1 arg2

The <additional args> are passed to the process from the command line when executing the hashbang script.

The hashbang execution is determined by checking if the first or second parameter is an executable file. If the executable file is on the second parameter, the first parameter is split based on syntax rules of /bin/sh, and the modified arguments are written back into the given slice (which usually should be &os.Args). This allows specifying multiple parameters in the hashbang header of a script, which are usually passed into the executable as one single parameter string.

The return value is the index of the script file in the argument slice. If it is 0, no hashbang execution was detected.

func ParseMap added in v0.0.10

func ParseMap(data string) map[string]string

ParseMap invokes ParseOrderedMap, and returns the results as an unordered map

func ParseOrderedMap added in v0.0.10

func ParseOrderedMap(data string) ([]string, []string)

ParseOrderedMap parses a string that was formatted by FormatMap or FormatOrderedMap and returns the contained key-value pairs as ordered slices. Keys and values are trimmed of whitespace. Entries that do not contain ValueSeparator result in keys empty map values. Entirely empty entries are ignored.

func ParseSlice added in v0.0.23

func ParseSlice(data string) []string

ParseSlice splits the given string on occurrences of `EntrySeparator` and trims all entries. Empty entries are ignored.

func ParseTime

func ParseTime(layout string, timeStr string) time.Time

Call time.Parse(), and panic if there is a non-nil error. Intended for static initializers with proven correct input values, similar to regexp.MustCompile.

func PluginSearchPath

func PluginSearchPath() ([]string, error)

PluginSearchPath returns a list of directories that can be used to search for plugins. It contains all directories from the PATH environment variable, all bin/ subdirectories of the GOPATH environment variable, the current working directory and the directory of the current executable. The result is sorted and does not contain duplicates.

func Printerr

func Printerr(err error)

Printerr prints an error message, if the given error is non-nil.

func ProfileCpu

func ProfileCpu() func()

ProfileCpu initiates memory and CPU profiling if any of the CpuProfileFile and MemProfileFile is set to non-empty strings, respectively. The function returns a tear-down function that must be called before the program exists in order to flush the profiling data to the output files. It can be used like this:

defer golib.ProfileCpu()()

func ReadRune

func ReadRune(input string) (theRune string, rest string, runeWidth int)

ReadRune reads one utf8 rune from the input string and provides information about the character width of the read rune.

func RegisterFlags

func RegisterFlags(flags Flags)

RegisterFlags registers various flags provided by the golib package, controlled by the bit-mask parameter.

func RegisterLogFlags

func RegisterLogFlags()

RegisterLogFlags registers flags for changing variables that will control the log level and other logging parameters when calling ConfigureLogging().

func RegisterProfileFlags

func RegisterProfileFlags()

RegisterProfileFlags registers flags to configure the CpuProfileFile and MemProfileFile by user-provided flags.

func RegisterTaskFlags

func RegisterTaskFlags()

RegisterTaskFlags registers flags for controlling the global variables TaskStopTimeout and PrintTaskStopWait, which can be used to debug shutdown sequences when using TaskGroups.

func RemoveDuplicates

func RemoveDuplicates(strings []string) []string

RemoveDuplicates sorts the given string slice and returns a copy with all duplicate strings removed.

func StringLength

func StringLength(str string) (strlen int)

StringLength returns the number of normalized utf8-runes within the cleaned string. Clean means the string is stripped of terminal escape characters and color codes.

func Substring

func Substring(str string, iFrom int, iTo int) string

Substring returns a substring of the given input string, but the indices iFrom and iTo point to normalized utf8-runes within the cleaned string. Clean means the string is stripped of terminal escape characters and color codes. The total number of normalized utf8 runes in the clean string can be obtained from the StringLength() function. All runes and special codes will be preserved in the output string.

func WaitForAny

func WaitForAny(channels []StopChan) int

WaitForAny returns if any of the give StopChan values are stopped. The implementation/ uses the reflect package to create a select-statement of variable size.

Exception: Uninitialized StopChans (created through the nil-value StopChan{}) are ignored, although they behave like stopped StopChans otherwise.

The return value is the index of the StopChan that caused this function to return. If the given channel slice is empty, or if it contains only uninitialized StopChan instances, the return value will be -1.

Types

type AbstractTestSuite added in v0.0.24

type AbstractTestSuite struct {
	*require.Assertions
	// contains filtered or unexported fields
}

func (*AbstractTestSuite) SetT added in v0.0.24

func (s *AbstractTestSuite) SetT(t *testing.T)

func (*AbstractTestSuite) SubTest added in v0.0.24

func (s *AbstractTestSuite) SubTest(name string, test func())

func (*AbstractTestSuite) SubTestSuite added in v0.0.24

func (s *AbstractTestSuite) SubTestSuite(testingSuite suite.TestingSuite)

func (*AbstractTestSuite) T added in v0.0.24

func (s *AbstractTestSuite) T() *testing.T

type BoolCondition

type BoolCondition struct {
	*sync.Cond
	Val bool
}

func NewBoolCondition

func NewBoolCondition() *BoolCondition

func (*BoolCondition) Broadcast

func (cond *BoolCondition) Broadcast()

func (*BoolCondition) Signal

func (cond *BoolCondition) Signal()

func (*BoolCondition) Unset

func (cond *BoolCondition) Unset()

func (*BoolCondition) Wait

func (cond *BoolCondition) Wait()

func (*BoolCondition) WaitAndUnset

func (cond *BoolCondition) WaitAndUnset()

type CleanupTask

type CleanupTask struct {
	// Cleanup will be executed when this Task is stopped.
	Cleanup func()
	// Description should be set to something that describes the purpose of this task.
	Description string
	// contains filtered or unexported fields
}

CleanupTask is an implementation of the Task interface that executes a cleanup routine when the task is stopped. The task itself does not do anything.

func (*CleanupTask) Start

func (task *CleanupTask) Start(*sync.WaitGroup) StopChan

Start implements the Task interface by returning the nil-value of StopChan, which indicates that this task does not actively do anything.

func (*CleanupTask) Stop

func (task *CleanupTask) Stop()

Stop implements the Task interface by executing the configured Cleanup function exactly once.

func (*CleanupTask) String

func (task *CleanupTask) String() string

String implements the Task interface by using the user-defined Description field.

type Command

type Command struct {
	// Program is name of the executable that will be started as a subprocess
	Program string
	// Args are the arguments that will be passed to the spawned subprocess.
	Args []string

	// ShortName can optionally be set to a concise string describing the command
	// to make log messages more descriptive. Otherwise, the value of the Program field will be used.
	ShortName string

	// LogDir can be set together with Logfile to redirect the stderr and stdout
	// streams of the subprocess. A suffix is a appended to the given file to make
	// sure it does not exist.
	LogDir string
	// See LogDir
	LogFile string

	// PreserveStdout set to true will lead the subprocess to redirect its stdout and stderr streams to the
	// streams of the parent process (which is the default when launching processes). This flag is ignored when
	// LogDir and LogFile is set.
	PreserveStdout bool

	// Proc will be initialized when calling Start() and points to the running subprocess.
	Proc *os.Process

	// State and StateErr will be initialized when the subprocess exits and give information
	// about the exit state of the process.
	State *os.ProcessState
	// See State
	StateErr error
	// contains filtered or unexported fields
}

Command starts a subprocess and optionally redirects the stdout and stderr streams to a log file. Command implements implements the Task interface: the subprocess can be stopped on demand, and the StopChan returns from the Start() method will be closed after the subprocess exists.

func (*Command) IsFinished

func (command *Command) IsFinished() bool

IsFinished returns true if the subprocess has been started and then exited afterwards.

func (*Command) Start

func (command *Command) Start(wg *sync.WaitGroup) StopChan

Start implements the Task interface. It starts the process and returns a StopChan, that will be closed after the subprocess exits.

func (*Command) StateString

func (command *Command) StateString() string

StateString returns a descriptive string about the state of the subprocess.

func (*Command) Stop

func (command *Command) Stop()

Stop implements the Task interface and tries to stop the subprocess by sending it the SIGHUP signal. TODO try other measures to kill the subprocess, if it does not finish after a timeout.

func (*Command) String

func (command *Command) String() string

String returns readable information about the process state and the logfile that contains stdout and stderr.

func (*Command) Success

func (command *Command) Success() bool

Success returns true, if the subprocess has been started and finished successfully.

type Flags

type Flags uint32

Flags is a bit-mask type used in the RegisterFlags() function.

type GinFileLogger added in v0.0.7

type GinFileLogger struct {
	Filename   string
	LogBody    bool
	LogHeaders bool
}

func (*GinFileLogger) LogRequest added in v0.0.7

func (l *GinFileLogger) LogRequest(context *gin.Context)

type GinLogHandler added in v0.0.7

type GinLogHandler struct {
	Logger *log.Logger

	// Handler can be set to a function to chose the log level and log message for every request.
	// If false is returned as second return value, a default log level will be chosen.
	// The default log level is Info, except if the context contains errors (then it's Error).
	// The returned string message can be empty.
	Handler func(ctx *gin.Context) (log.Level, string, bool)
}

func (*GinLogHandler) LogRequest added in v0.0.7

func (h *GinLogHandler) LogRequest(c *gin.Context)

type GinTask

type GinTask struct {
	*gin.Engine
	Endpoint     string
	ShutdownHook func()
	// contains filtered or unexported fields
}

func NewGinTask added in v0.0.2

func NewGinTask(endpoint string) *GinTask

func NewGinTaskWithHandler added in v0.0.8

func NewGinTaskWithHandler(endpoint string, logHandler *GinLogHandler) *GinTask

func (*GinTask) Start added in v0.0.2

func (task *GinTask) Start(wg *sync.WaitGroup) StopChan

func (*GinTask) Stop added in v0.0.2

func (task *GinTask) Stop()

func (*GinTask) String added in v0.0.2

func (task *GinTask) String() string

type KeyValueStringSlice

type KeyValueStringSlice struct {
	Keys   []string
	Values []string
}

KeyValueStringSlice implements the flag.Value interface. It expects value of the form 'key=value' and splits them into the corresponding parts.

func SplitMapKeysAndValues added in v0.0.25

func SplitMapKeysAndValues(m map[string]string) KeyValueStringSlice

SplitMapKeysAndValues returns a KeyValueStringSlice that holds the keys and values of the input map.

func (*KeyValueStringSlice) Delete

func (k *KeyValueStringSlice) Delete(key string)

Delete deletes all instances of the given key from the receiving KeyValueStringSlice. If the key is not present, the receiver remains unchanged.

func (*KeyValueStringSlice) Len added in v0.0.25

func (k *KeyValueStringSlice) Len() int

func (*KeyValueStringSlice) Less added in v0.0.25

func (k *KeyValueStringSlice) Less(i, j int) bool

func (*KeyValueStringSlice) Map

func (k *KeyValueStringSlice) Map() map[string]string

Map returns a map-representation of the contained key-value pairs.

func (*KeyValueStringSlice) Put

func (k *KeyValueStringSlice) Put(key, value string)

Put sets the given value to the first instance of the given key. All other instances of the given key remain unchanged. If the key is not yet present in the receiver, the new key-value pair is appended.

func (*KeyValueStringSlice) Set

func (k *KeyValueStringSlice) Set(value string) error

Set implements the flag.Value interface by splitting the 'key=value' string and returning an error if the format is wrong.

func (*KeyValueStringSlice) String

func (k *KeyValueStringSlice) String() string

String implements the flag.Value interface by printing all contains key-value pairs.

func (*KeyValueStringSlice) Swap added in v0.0.25

func (k *KeyValueStringSlice) Swap(i, j int)

type LoopTask

type LoopTask struct {
	// StopChan is added as an anonymous field, which allows direct access to the
	// Stop() method and other methods that control the execution of the loop.
	StopChan

	// Description should be set to something that describes the purpose of this loop task.
	Description string

	// StopHook can optionally be set to a callback function, which will be executed
	// after the loop is finished (but before the underlying StopChan is stopped).
	StopHook func()

	// Loop defines the loop iteration. The stop parameter can be used to query the current
	// state of the task, or to call WaitTimeout() to control the frequency of the loop.
	// If the return value is non-nil, the task will be stopped. If the return value
	// is StopLoopTask, the task will be stopped without reporting an error.
	Loop func(stop StopChan) error
}

LoopTask is an implementation of the Task interface that spawns a worker goroutine that executes a loop until the task is stopped or an error is encountered.

func (LoopTask) Err

func (s LoopTask) Err() error

Err returns the error value stored in the StopChan. It will always be nil, if the StopChan has not been stopped yet, but can also be nil for a stopped StopChan.

func (LoopTask) Execute

func (s LoopTask) Execute(execute func())

Execute executes the given function while grabbing the internal lock of the StopChan. This means that no other goroutine can stop the StopChan while the function is running, and that it is mutually exclusive with any of the IfStopped etc. methods. This is sometimes useful, if the StopChan is used for its locking capabilities.

func (LoopTask) IfElseStopped

func (s LoopTask) IfElseStopped(stopped func(), notStopped func())

IfElseStopped executes one of the two given functions, depending on the stopped state of the StopChan. This call guarantees that the StopChan is not stopped while any of the functions is being executed.

func (LoopTask) IfNotStopped

func (s LoopTask) IfNotStopped(execute func())

IfNotStopped executes the given function, iff the receiving StopChan is already stopped. If another goroutine is currently stopping this StopChan (see StopErrFunc), IfNotStopped waits until the StopChan is finally stopped before executing the callback.

func (LoopTask) IfStopped

func (s LoopTask) IfStopped(execute func())

IfStopped executes the given function, iff the receiving StopChan is not yet stopped. This call guarantees that the StopChan is not stopped while the function is being executed.

func (LoopTask) IsNil

func (s LoopTask) IsNil() bool

IsNil returns true, if the receiving StopChan is its nil-values. See the StopChan documentation for details on the behavior of the nil value.

func (*LoopTask) Start

func (task *LoopTask) Start(wg *sync.WaitGroup) StopChan

Start implements the Task interface by spawning a goroutine that executes a loop until the task is stopped or the loop iteration returns an error.

func (LoopTask) Stop

func (s LoopTask) Stop()

Stop stops the receiving StopChan without storing any error value.

func (LoopTask) StopErr

func (s LoopTask) StopErr(err error)

StopErr stops the receiving StopChan, iff it was not already stopped. The given error value is stored in the StopChan.

func (LoopTask) StopErrFunc

func (s LoopTask) StopErrFunc(perform func() error)

StopErrFunc stops the receiving StopChan, iff it is not already stopped. In that case, the given function is executed and the resulting error value is stored within the StopChan.

func (LoopTask) StopFunc

func (s LoopTask) StopFunc(perform func())

StopFunc stops the receiving StopChan and executes the given function, iff it was not already stopped.

func (LoopTask) Stopped

func (s LoopTask) Stopped() bool

Stopped returns whether the StopChan is stopped or not. It blocks, if the StopChan is currently being stopped by another goroutine.

func (*LoopTask) String

func (task *LoopTask) String() string

String returns a description of the task using the user-defined Description value.

func (LoopTask) Wait

func (s LoopTask) Wait()

Wait blocks until the receiving StopChan is stopped.

func (LoopTask) WaitChan

func (s LoopTask) WaitChan() <-chan error

WaitChan returns a channel that is closed as soon as the receiving StopChan is stopped. The returned channel never receives any values. The Err() method can be used to retrieve the error instance stored in the StopChan afterwards.

To avoid memory leaks, only one channel is lazily created per StopChan instance, accompanied by one goroutine that closes that channel after waiting for the StopChan to be stopped. The same channel will be returned by all calls to WaitChan().

func (LoopTask) WaitTimeout

func (s LoopTask) WaitTimeout(t time.Duration) bool

WaitTimeout waits for the StopChan to be stopped, but returns if the given time duration has passed without that happening. The return value indicates which one of the two happened:

  1. Return true means the wait timed out and the StopChan is still active.
  2. Return false means the StopChan was stopped before the timeout expired.

func (LoopTask) WaitTimeoutPrecise

func (s LoopTask) WaitTimeoutPrecise(totalTimeout time.Duration, wakeupFactor float64, lastTimePointer *time.Time) bool

WaitTimeoutLoop behaves like WaitTimeout, but tries to achieve a more precise timeout timing by waking up frequently and checking the passed sleep time. The wakeupFactor parameter must be in ]0..1] or it is adjusted to 1. It is multiplied with the totalDuration to determine the sleep duration of intermediate sleeps for increasing the sleep duration accuracy in high-load situations. For example, a wakeupFactor of 0.1 will lead to 10 intermediate wake-ups that check if the desired sleep time has passed already. If the lastTime parameter is not nil and not zero, the sleep time will be counted not from time.Now(), but from the stored time. If the lastTime parameter is not zero, the current time is stored into it before returning.

type MultiError

type MultiError []error

MultiError is a helper type for combining multiple error values into one.

func (*MultiError) Add

func (err *MultiError) Add(errOrNil error)

Add adds the given error to the MultiError, if it is not nil.

func (*MultiError) AddMulti

func (err *MultiError) AddMulti(possibleErrors ...interface{})

func (MultiError) Error

func (err MultiError) Error() string

Error implements the error interface by printing all contained errors on a separate line.

func (MultiError) NilOrError

func (err MultiError) NilOrError() error

NilOrError returns either nil, the only contained error, or the entire MultiError, depending on the number of contained errors.

type NoopTask

type NoopTask struct {
	// Chan will be returns from the Start() method and stopped by the Stop() method.
	Chan StopChan
	// Description should be set to something that describes the purpose of this task.
	Description string
}

NoopTask is a trivial implementation of the Task interface that uses a user-defined instance of StopChan. It can be used to wrap arbitrary instances of StopChan in the Task interface.

func ExternalInterruptTask

func ExternalInterruptTask() *NoopTask

ExternalInterruptTask returns a Task that automatically stops when the SIGINT signal is received (e.g. by pressing Ctrl-C).

func StdinClosedTask

func StdinClosedTask() *NoopTask

StdinClosedTask returns a Task that automatically stops when the standard input stream is closed.

func UserInputTask

func UserInputTask() *NoopTask

UserInputTask returns a Task that automatically stops when a newline character is received on the standard input (See UserInput()).

func (*NoopTask) Start

func (task *NoopTask) Start(*sync.WaitGroup) StopChan

Start returns the provided StopChan instance.

func (*NoopTask) Stop

func (task *NoopTask) Stop()

Stop stops the provided StopChan instance.

func (*NoopTask) String

func (task *NoopTask) String() string

String returns a description of the task based on the user-defined Description field.

type RankedItem

type RankedItem struct {
	Rank float64
	Item interface{}
}

type RankedSlice

type RankedSlice []RankedItem

func (*RankedSlice) Append

func (r *RankedSlice) Append(rank float64, item interface{})

func (RankedSlice) Items

func (r RankedSlice) Items() []interface{}

func (RankedSlice) ItemsSorted

func (r RankedSlice) ItemsSorted() []interface{}

func (RankedSlice) ItemsSortedReverse

func (r RankedSlice) ItemsSortedReverse() []interface{}

func (RankedSlice) Len

func (r RankedSlice) Len() int

func (RankedSlice) Less

func (r RankedSlice) Less(i, j int) bool

func (RankedSlice) Sort

func (r RankedSlice) Sort()

func (RankedSlice) SortReverse

func (r RankedSlice) SortReverse()

func (RankedSlice) Swap

func (r RankedSlice) Swap(i, j int)

type SetupTask added in v0.0.22

type SetupTask struct {
	// Setup will be executed when this Task is started.
	Setup func()
	// Description should be set to something that describes the purpose of this task.
	Description string
}

SetupTask is an implementation of the Task interface that executes a set routine when the task is started. The task itself does not do anything.

func (*SetupTask) Start added in v0.0.22

func (task *SetupTask) Start(*sync.WaitGroup) StopChan

Start implements the Task interface by executing the Setup routine and returning the nil-value of StopChan, which indicates that this task does not actively do anything.

func (*SetupTask) Stop added in v0.0.22

func (task *SetupTask) Stop()

Stop implements the Task interface and does nothing.

func (*SetupTask) String added in v0.0.22

func (task *SetupTask) String() string

String implements the Task interface by using the user-defined Description field.

type Startable

type Startable interface {
	// The Start() method will be called exactly once and should fully initialize and start
	// the underlying task. If this involves creating goroutines, they should be registered
	// in the given *sync.WaitGroup. The resulting StopChan must be closed by the task when it finishes,
	// optionally logging an error explaining the reason for stopping prematurely.
	// When stopping, all goroutines must exit as well, reducing the counter in the WaitGroup.
	//
	// Note: Returning the uninitialized nil-value (StopChan{}) indicates that the task
	// will never shut down on its own, i.e. the task is not capable of producing an error.
	//
	// If an error happens immediately inside the Start() method, NewStoppedChan(err) should be returned.
	Start(wg *sync.WaitGroup) StopChan
}

Startable objects can be started and notify a controlling instance when they finish. The main interface for this is the Task interface. The Startable interface is extracted to make the signature of the Start() method reusable.

type StopChan

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

StopChan is a utility type for coordinating concurrent goroutines. Initially, a StopChan is 'running' and can be stopped exactly once. Goroutines can wait for the StopChan to be stopped and query the current status in various ways.

When stopping a StopChan, an error instance can optionally be stored for later reference.

StopChan values should always be passed and stored by-value instead of by-reference, since they contain a pointer to the actual internal data.

The nil-value of StopChan (e.g. StopChan{}) mostly acts like an already-stopped StopChan with a nil error. The only exception is the WaitForAny() function, which will ignore uninitialized StopChans.

func ExternalInterrupt

func ExternalInterrupt() StopChan

ExternalInterrupt creates a StopChan that is automatically stopped as soon as an interrupt signal (like pressing Ctrl-C) is received. This can be used in conjunction with the NoopTask to create a task that automatically stops when the process receives an interrupt signal.

func NewStopChan

func NewStopChan() StopChan

NewStopChan allocates a new, un-stopped StopChan.

func NewStoppedChan

func NewStoppedChan(err error) StopChan

NewStoppedChan returns a StopChan that is already stopped, and contains the given error value.

func StdinClosed

func StdinClosed() StopChan

StdinClosed creates a StopChan that is automatically stopped when the standard input stream is closed. This can be used in conjunction with the NoopTask to create a task that automatically stops when the user presses Ctrl-D or stdin is closed for any other reason. This should not be user if the standard input is used for different purposes.

func UserInput

func UserInput() StopChan

UserInput creates a StopChan that is automatically stopped when the a newline character is received on os.Stdin. This can be used in conjunction with the NoopTask to create a task that automatically stops when the user presses the enter key. This should not be used if the standard input is used for different purposes.

func WaitErrFunc

func WaitErrFunc(wg *sync.WaitGroup, wait func() error) StopChan

WaitErrFunc executes the given function and returns a StopChan, that will automatically be stopped after the function finishes. The error instance return by the function will be stored in the StopChan.

func WaitForSetup

func WaitForSetup(wg *sync.WaitGroup, setup func() error) StopChan

WaitForSetup executes the given function and returns a StopChan, that will be stopped after the function finishes, but ONLY if the function returns a non-nil error value. In that case the returned error is stored in the stopped StopChan.

This behaviour is similar to WaitErrFunc, but it leaves the StopChan active if the setup function finished successfully.

func WaitFunc

func WaitFunc(wg *sync.WaitGroup, wait func()) StopChan

WaitErrFunc executes the given function and returns a StopChan, that will automatically be stopped after the function finishes.

func (StopChan) Err

func (s StopChan) Err() error

Err returns the error value stored in the StopChan. It will always be nil, if the StopChan has not been stopped yet, but can also be nil for a stopped StopChan.

func (StopChan) Execute

func (s StopChan) Execute(execute func())

Execute executes the given function while grabbing the internal lock of the StopChan. This means that no other goroutine can stop the StopChan while the function is running, and that it is mutually exclusive with any of the IfStopped etc. methods. This is sometimes useful, if the StopChan is used for its locking capabilities.

func (StopChan) IfElseStopped

func (s StopChan) IfElseStopped(stopped func(), notStopped func())

IfElseStopped executes one of the two given functions, depending on the stopped state of the StopChan. This call guarantees that the StopChan is not stopped while any of the functions is being executed.

func (StopChan) IfNotStopped

func (s StopChan) IfNotStopped(execute func())

IfNotStopped executes the given function, iff the receiving StopChan is already stopped. If another goroutine is currently stopping this StopChan (see StopErrFunc), IfNotStopped waits until the StopChan is finally stopped before executing the callback.

func (StopChan) IfStopped

func (s StopChan) IfStopped(execute func())

IfStopped executes the given function, iff the receiving StopChan is not yet stopped. This call guarantees that the StopChan is not stopped while the function is being executed.

func (StopChan) IsNil

func (s StopChan) IsNil() bool

IsNil returns true, if the receiving StopChan is its nil-values. See the StopChan documentation for details on the behavior of the nil value.

func (StopChan) Stop

func (s StopChan) Stop()

Stop stops the receiving StopChan without storing any error value.

func (StopChan) StopErr

func (s StopChan) StopErr(err error)

StopErr stops the receiving StopChan, iff it was not already stopped. The given error value is stored in the StopChan.

func (StopChan) StopErrFunc

func (s StopChan) StopErrFunc(perform func() error)

StopErrFunc stops the receiving StopChan, iff it is not already stopped. In that case, the given function is executed and the resulting error value is stored within the StopChan.

func (StopChan) StopFunc

func (s StopChan) StopFunc(perform func())

StopFunc stops the receiving StopChan and executes the given function, iff it was not already stopped.

func (StopChan) Stopped

func (s StopChan) Stopped() bool

Stopped returns whether the StopChan is stopped or not. It blocks, if the StopChan is currently being stopped by another goroutine.

func (StopChan) Wait

func (s StopChan) Wait()

Wait blocks until the receiving StopChan is stopped.

func (StopChan) WaitChan

func (s StopChan) WaitChan() <-chan error

WaitChan returns a channel that is closed as soon as the receiving StopChan is stopped. The returned channel never receives any values. The Err() method can be used to retrieve the error instance stored in the StopChan afterwards.

To avoid memory leaks, only one channel is lazily created per StopChan instance, accompanied by one goroutine that closes that channel after waiting for the StopChan to be stopped. The same channel will be returned by all calls to WaitChan().

func (StopChan) WaitTimeout

func (s StopChan) WaitTimeout(t time.Duration) bool

WaitTimeout waits for the StopChan to be stopped, but returns if the given time duration has passed without that happening. The return value indicates which one of the two happened:

  1. Return true means the wait timed out and the StopChan is still active.
  2. Return false means the StopChan was stopped before the timeout expired.

func (StopChan) WaitTimeoutPrecise

func (s StopChan) WaitTimeoutPrecise(totalTimeout time.Duration, wakeupFactor float64, lastTimePointer *time.Time) bool

WaitTimeoutLoop behaves like WaitTimeout, but tries to achieve a more precise timeout timing by waking up frequently and checking the passed sleep time. The wakeupFactor parameter must be in ]0..1] or it is adjusted to 1. It is multiplied with the totalDuration to determine the sleep duration of intermediate sleeps for increasing the sleep duration accuracy in high-load situations. For example, a wakeupFactor of 0.1 will lead to 10 intermediate wake-ups that check if the desired sleep time has passed already. If the lastTime parameter is not nil and not zero, the sleep time will be counted not from time.Now(), but from the stored time. If the lastTime parameter is not zero, the current time is stored into it before returning.

type StringSlice

type StringSlice []string

StringSlice implements the flag.Value interface and stores every occurrence of the according flag in one string slice.

func (*StringSlice) Set

func (i *StringSlice) Set(value string) error

Set implements the flag.Value interface by adding the given string to the underlying string slice.

func (*StringSlice) String

func (i *StringSlice) String() string

String implements the flag.Value interface by printing the contents of the underlying string slice.

type TCPConnectionHandler

type TCPConnectionHandler func(wg *sync.WaitGroup, conn *net.TCPConn)

TCPConnectionHandler is a callback function for TCPListenerTask, which is invoked whenever a new TCP connection is successfully accepted.

type TCPListenerTask

type TCPListenerTask struct {
	*LoopTask

	// ListenEndpoint is the TCP endpoint to open a TCP listening socket on.
	ListenEndpoint string

	// Handler is a required callback-function that will be called for every
	// successfully established TCP connection. It is not called in a separate
	// goroutine, so it should fork a new routine for long-running connections.
	// The handler is always executed while the StopChan in the underlying
	// LoopTask is locked.
	Handler TCPConnectionHandler

	// StopHook is an optional callback that is invoked after the task stops and
	// the listening TCP socket is closed. When StopHook is executed, the underlying
	// LoopTask/StopChan is NOT locked, so helpers methods like Execute() must be used
	// if synchronization is required.
	StopHook func()
	// contains filtered or unexported fields
}

TCPListenerTask is an implementation of the Task interface that listens for incoming TCP connections on a given TCP endpoint. A handler function is invoked for every accepted TCP connection, and an optional hook can be executed when the TCP socket is closed and the task stops.

func (TCPListenerTask) Err

func (s TCPListenerTask) Err() error

Err returns the error value stored in the StopChan. It will always be nil, if the StopChan has not been stopped yet, but can also be nil for a stopped StopChan.

func (TCPListenerTask) Execute

func (s TCPListenerTask) Execute(execute func())

Execute executes the given function while grabbing the internal lock of the StopChan. This means that no other goroutine can stop the StopChan while the function is running, and that it is mutually exclusive with any of the IfStopped etc. methods. This is sometimes useful, if the StopChan is used for its locking capabilities.

func (*TCPListenerTask) ExtendedStart

func (task *TCPListenerTask) ExtendedStart(start func(addr net.Addr), wg *sync.WaitGroup) StopChan

ExtendedStart creates the TCP listen socket and starts accepting incoming connections. In addition, a hook function can be defined that will be called once after the socket has been opened successfully and is passed the resolved address of the TCP endpoint.

func (TCPListenerTask) IfElseStopped

func (s TCPListenerTask) IfElseStopped(stopped func(), notStopped func())

IfElseStopped executes one of the two given functions, depending on the stopped state of the StopChan. This call guarantees that the StopChan is not stopped while any of the functions is being executed.

func (TCPListenerTask) IfNotStopped

func (s TCPListenerTask) IfNotStopped(execute func())

IfNotStopped executes the given function, iff the receiving StopChan is already stopped. If another goroutine is currently stopping this StopChan (see StopErrFunc), IfNotStopped waits until the StopChan is finally stopped before executing the callback.

func (TCPListenerTask) IfStopped

func (s TCPListenerTask) IfStopped(execute func())

IfStopped executes the given function, iff the receiving StopChan is not yet stopped. This call guarantees that the StopChan is not stopped while the function is being executed.

func (TCPListenerTask) IsNil

func (s TCPListenerTask) IsNil() bool

IsNil returns true, if the receiving StopChan is its nil-values. See the StopChan documentation for details on the behavior of the nil value.

func (*TCPListenerTask) Start

func (task *TCPListenerTask) Start(wg *sync.WaitGroup) StopChan

Start implements the Task interface. It opens the TCP listen socket and starts accepting incoming connections.

func (*TCPListenerTask) Stop

func (task *TCPListenerTask) Stop()

Stop extends the Stop() function inherited from LoopTask/StopChan and additionally closes the TCP listening socket.

func (*TCPListenerTask) StopErr

func (task *TCPListenerTask) StopErr(err error)

StopErr extends the StopErr() function inherited from LoopTask/StopChan and additionally closes the TCP listening socket.

func (*TCPListenerTask) StopErrFunc

func (task *TCPListenerTask) StopErrFunc(perform func() error)

StopErrFunc extends the StopErrFunc() function inherited from LoopTask/StopChan and additionally closes the TCP listening socket.

func (*TCPListenerTask) StopFunc

func (task *TCPListenerTask) StopFunc(perform func())

StopFunc extends the StopFunc() function inherited from LoopTask/StopChan and additionally closes the TCP listening socket.

func (TCPListenerTask) Stopped

func (s TCPListenerTask) Stopped() bool

Stopped returns whether the StopChan is stopped or not. It blocks, if the StopChan is currently being stopped by another goroutine.

func (*TCPListenerTask) String

func (task *TCPListenerTask) String() string

String implements the Task interface by returning a descriptive string.

func (TCPListenerTask) Wait

func (s TCPListenerTask) Wait()

Wait blocks until the receiving StopChan is stopped.

func (TCPListenerTask) WaitChan

func (s TCPListenerTask) WaitChan() <-chan error

WaitChan returns a channel that is closed as soon as the receiving StopChan is stopped. The returned channel never receives any values. The Err() method can be used to retrieve the error instance stored in the StopChan afterwards.

To avoid memory leaks, only one channel is lazily created per StopChan instance, accompanied by one goroutine that closes that channel after waiting for the StopChan to be stopped. The same channel will be returned by all calls to WaitChan().

func (TCPListenerTask) WaitTimeout

func (s TCPListenerTask) WaitTimeout(t time.Duration) bool

WaitTimeout waits for the StopChan to be stopped, but returns if the given time duration has passed without that happening. The return value indicates which one of the two happened:

  1. Return true means the wait timed out and the StopChan is still active.
  2. Return false means the StopChan was stopped before the timeout expired.

func (TCPListenerTask) WaitTimeoutPrecise

func (s TCPListenerTask) WaitTimeoutPrecise(totalTimeout time.Duration, wakeupFactor float64, lastTimePointer *time.Time) bool

WaitTimeoutLoop behaves like WaitTimeout, but tries to achieve a more precise timeout timing by waking up frequently and checking the passed sleep time. The wakeupFactor parameter must be in ]0..1] or it is adjusted to 1. It is multiplied with the totalDuration to determine the sleep duration of intermediate sleeps for increasing the sleep duration accuracy in high-load situations. For example, a wakeupFactor of 0.1 will lead to 10 intermediate wake-ups that check if the desired sleep time has passed already. If the lastTime parameter is not nil and not zero, the sleep time will be counted not from time.Now(), but from the stored time. If the lastTime parameter is not zero, the current time is stored into it before returning.

type Task

type Task interface {
	Startable

	// Stop should be idempotent and cause the underlying task to stop on-demand.
	// It might be called multiple times, and it might also be called if the StopChan
	// is stopped prematurely due to an error.
	// The StopChan returned from Start() must be stopped after the Task finishes,
	// regardless whether Stop() has been called or not.
	Stop()

	// String returns a concise and human-readable description of the task.
	String() string
}

Task is an interface for coordinated setup and tear-down of applications or objects. The Task interface defines a simple lifecycle. First, it is started through Start(). It runs until it finishes or produces an error. After any of these, the StopChan returned from the Start() method must be stopped by the task.

When the StopChan is stopped, the Task must be completely inactive, including exiting any goroutines that have been created for its operation.

type TaskGroup

type TaskGroup []Task

TaskGroup is a collection of stoppable tasks that can be started and stopped together. The purpose of this type is to coordinate the startup and shutdown sequences of multiple parts of one application or object.

func (*TaskGroup) Add

func (group *TaskGroup) Add(tasks ...Task)

Add adds the given tasks to the task group.

func (TaskGroup) CollectErrors

func (group TaskGroup) CollectErrors(channels []StopChan, do func(err error)) (numErrors int)

CollectErrors waits for the given StopChan instances to stop and calls the given callback function for every collected non-nil error instance.

The channels slice must be the one created by StartTasks().

If the global PrintTaskStopWait variable is true, and additional log message is printed when starting waiting for a task. This can be used to identify the task that prevents the shutdown from progressing.

func (TaskGroup) CollectMultiError

func (group TaskGroup) CollectMultiError(channels []StopChan) MultiError

CollectMultiError uses CollectErrors to collect all errors returned from all StopChan instances into one MultiError object.

The channels slice must be the one created by StartTasks().

func (TaskGroup) PrintWaitAndStop

func (group TaskGroup) PrintWaitAndStop() int

PrintWaitAndStop calls WaitAndStop() using the global variable TaskStopTimeout as the timeout parameter. Afterwards, the task that caused the shutdown is printed as a debug log-message and the number of errors encountered is returned. This is a convenience function that can be used in main() functions.

func (TaskGroup) StartTasks

func (group TaskGroup) StartTasks(wg *sync.WaitGroup) []StopChan

StartTasks starts all tasks in the task group and returns the created StopChan instances in the same order as the tasks.

func (TaskGroup) Stop

func (group TaskGroup) Stop()

Stop stops all tasks in the task group in parallel. Stop blocks until all Stop() invocations of all tasks have returned.

If the global PrintTaskStopWait variable is set, a log message is printed before stopping every task.

func (TaskGroup) WaitAndStop

func (group TaskGroup) WaitAndStop(timeout time.Duration) (Task, int)

WaitAndStop executes the entire lifecycle sequence for all tasks in the task group: - Start all tasks using StartTasks() with a new instance of sync.WaitGroup - Wait for the first task to finish - Stop all tasks using Stop() - Wait until all goroutines end using sync.WaitGroup.Wait() - Wait until all tasks finish using CollectErrors()

All errors produced by any task are logged. Afterwards, the task that caused the shutdown is returned, as well as the number of errors encountered.

If the timeout parameter is >0, a timer will be started before stopping all tasks. After the timer expires, all goroutines will be dumped to the standard output and the program will terminate. This can be used to debug the task shutdown sequence, in case one task does not shut down properly, e.g. due to a deadlock.

type TimeoutCond

type TimeoutCond struct {
	L sync.Locker
	// contains filtered or unexported fields
}

Like sync.Cond, but supports WaitTimeout() instead of Signal()

func NewTimeoutCond

func NewTimeoutCond(l sync.Locker) *TimeoutCond

func (*TimeoutCond) Broadcast

func (c *TimeoutCond) Broadcast()

func (*TimeoutCond) Wait

func (c *TimeoutCond) Wait()

func (*TimeoutCond) WaitTimeout

func (c *TimeoutCond) WaitTimeout(t time.Duration)

type TimeoutTask

type TimeoutTask struct {
	Timeout        time.Duration
	ErrorMessage   string
	DumpGoroutines bool
	// contains filtered or unexported fields
}

TimeoutTask is a Task that automatically fails after a predefined time. If the task is stopped before the timeout expires, no errors is logged. If DumpGoroutines is set to true, all running goroutines will be printed when a timeout occurs.

func (*TimeoutTask) Start

func (t *TimeoutTask) Start(wg *sync.WaitGroup) StopChan

Start implements the Task interface

func (*TimeoutTask) Stop

func (t *TimeoutTask) Stop()

Stop implements the Task interface

func (*TimeoutTask) String

func (t *TimeoutTask) String() string

Stop implements the Task interface

type UDPListenerTask

type UDPListenerTask struct {
	*LoopTask

	// ListenEndpoint is the UDP endpoint to open a UDP listening socket on.
	ListenEndpoint string

	// Handler is a required callback-function that will be called for every
	// received UDP packet. It is not called in a separate
	// goroutine, so it should fork a new routine for long-running operations.
	// The handler is always executed while the StopChan in the underlying
	// LoopTask is locked.
	Handler UDPPacketHandler

	// StopHook is an optional callback that is invoked after the task stops and
	// the listening UDP socket is closed. When StopHook is executed, the underlying
	// LoopTask/StopChan is NOT locked, so helper methods like Execute() must be used
	// if synchronization is required.
	StopHook func()

	// The size of the buffer to receive UDP packets into. If the buffer size is smaller
	// than incoming packets, the UDPPacketHandler might be invoked multiple times with
	// different UDP packet fragments. The value of DefaultUdpPacketSize is used if this is
	// to <=0.
	PacketBufferSize int
	// contains filtered or unexported fields
}

UDPListenerTask is an implementation of the Task interface that listens for incoming UDP packets on a given UDP endpoint. A handler function is invoked for every received UDP packet, and an optional hook can be executed when the UDP socket is closed and the task stops.

func (UDPListenerTask) Err

func (s UDPListenerTask) Err() error

Err returns the error value stored in the StopChan. It will always be nil, if the StopChan has not been stopped yet, but can also be nil for a stopped StopChan.

func (UDPListenerTask) Execute

func (s UDPListenerTask) Execute(execute func())

Execute executes the given function while grabbing the internal lock of the StopChan. This means that no other goroutine can stop the StopChan while the function is running, and that it is mutually exclusive with any of the IfStopped etc. methods. This is sometimes useful, if the StopChan is used for its locking capabilities.

func (*UDPListenerTask) ExtendedStart

func (task *UDPListenerTask) ExtendedStart(start func(addr net.Addr), wg *sync.WaitGroup) StopChan

ExtendedStart creates the UDP listen socket and starts receiving incoming packets. In addition, a hook function can be defined that will be called once after the socket has been opened successfully and is passed the resolved address of the UDP endpoint.

func (UDPListenerTask) IfElseStopped

func (s UDPListenerTask) IfElseStopped(stopped func(), notStopped func())

IfElseStopped executes one of the two given functions, depending on the stopped state of the StopChan. This call guarantees that the StopChan is not stopped while any of the functions is being executed.

func (UDPListenerTask) IfNotStopped

func (s UDPListenerTask) IfNotStopped(execute func())

IfNotStopped executes the given function, iff the receiving StopChan is already stopped. If another goroutine is currently stopping this StopChan (see StopErrFunc), IfNotStopped waits until the StopChan is finally stopped before executing the callback.

func (UDPListenerTask) IfStopped

func (s UDPListenerTask) IfStopped(execute func())

IfStopped executes the given function, iff the receiving StopChan is not yet stopped. This call guarantees that the StopChan is not stopped while the function is being executed.

func (UDPListenerTask) IsNil

func (s UDPListenerTask) IsNil() bool

IsNil returns true, if the receiving StopChan is its nil-values. See the StopChan documentation for details on the behavior of the nil value.

func (*UDPListenerTask) Start

func (task *UDPListenerTask) Start(wg *sync.WaitGroup) StopChan

Start implements the Task interface. It opens the UDP listen socket and starts accepting incoming packets.

func (*UDPListenerTask) Stop

func (task *UDPListenerTask) Stop()

Stop extends the Stop() function inherited from LoopTask/StopChan and additionally closes the UDP listening socket.

func (*UDPListenerTask) StopErr

func (task *UDPListenerTask) StopErr(err error)

StopErr extends the StopErr() function inherited from LoopTask/StopChan and additionally closes the UDP listening socket.

func (*UDPListenerTask) StopErrFunc

func (task *UDPListenerTask) StopErrFunc(perform func() error)

StopErrFunc extends the StopErrFunc() function inherited from LoopTask/StopChan and additionally closes the UDP listening socket.

func (*UDPListenerTask) StopFunc

func (task *UDPListenerTask) StopFunc(perform func())

StopFunc extends the StopFunc() function inherited from LoopTask/StopChan and additionally closes the UDP listening socket.

func (UDPListenerTask) Stopped

func (s UDPListenerTask) Stopped() bool

Stopped returns whether the StopChan is stopped or not. It blocks, if the StopChan is currently being stopped by another goroutine.

func (*UDPListenerTask) String

func (task *UDPListenerTask) String() string

String implements the Task interface by returning a descriptive string.

func (UDPListenerTask) Wait

func (s UDPListenerTask) Wait()

Wait blocks until the receiving StopChan is stopped.

func (UDPListenerTask) WaitChan

func (s UDPListenerTask) WaitChan() <-chan error

WaitChan returns a channel that is closed as soon as the receiving StopChan is stopped. The returned channel never receives any values. The Err() method can be used to retrieve the error instance stored in the StopChan afterwards.

To avoid memory leaks, only one channel is lazily created per StopChan instance, accompanied by one goroutine that closes that channel after waiting for the StopChan to be stopped. The same channel will be returned by all calls to WaitChan().

func (UDPListenerTask) WaitTimeout

func (s UDPListenerTask) WaitTimeout(t time.Duration) bool

WaitTimeout waits for the StopChan to be stopped, but returns if the given time duration has passed without that happening. The return value indicates which one of the two happened:

  1. Return true means the wait timed out and the StopChan is still active.
  2. Return false means the StopChan was stopped before the timeout expired.

func (UDPListenerTask) WaitTimeoutPrecise

func (s UDPListenerTask) WaitTimeoutPrecise(totalTimeout time.Duration, wakeupFactor float64, lastTimePointer *time.Time) bool

WaitTimeoutLoop behaves like WaitTimeout, but tries to achieve a more precise timeout timing by waking up frequently and checking the passed sleep time. The wakeupFactor parameter must be in ]0..1] or it is adjusted to 1. It is multiplied with the totalDuration to determine the sleep duration of intermediate sleeps for increasing the sleep duration accuracy in high-load situations. For example, a wakeupFactor of 0.1 will lead to 10 intermediate wake-ups that check if the desired sleep time has passed already. If the lastTime parameter is not nil and not zero, the sleep time will be counted not from time.Now(), but from the stored time. If the lastTime parameter is not zero, the current time is stored into it before returning.

type UDPPacketHandler

type UDPPacketHandler func(wg *sync.WaitGroup, localAddr net.Addr, remoteAddr *net.UDPAddr, packet []byte)

UDPConnectionHandler is a callback function for UDPListenerTask, which is invoked whenever a new UDP packet is received.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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