connection

package module
v0.8.3 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2024 License: Apache-2.0 Imports: 15 Imported by: 5

README

Moov Banner Logo

Community channel #iso8583 · Blog

moov-io/iso8583-connection

Moov's mission is to give developers an easy way to create and integrate bank processing into their own software products. Our open source projects are each focused on solving a single responsibility in financial services and designed around performance, scalability, and ease of use.

moov-io/iso8583-connection is a package helping with sending, receiving and matching ISO 8583 messages between client and server. It can be used both for acquiring and issuing services.

Project status

ISO 8583 Connection package is used in production environments. Please star the project if you are interested in its progress. Please let us know if you encounter any bugs/unclear documentation or have feature suggestions by opening up an issue or pull request. Thanks!

Configuration

Following options are supported:

  • SendTimeout - sets the timeout for a Send operation
  • IdleTime - sets the period of inactivity (no messages sent) after which a ping message will be sent to the server
  • ReadTimeout - sets the period of time to wait between reads before calling ReadTimeoutHandler
  • PingHandler - called when no message was sent during idle time. It should be safe for concurrent use.
  • InboundMessageHandler - called when a message from the server is received or no matching request for the message was found. InboundMessageHandler must be safe to be called concurrenty.
  • ReadTimeoutHandler - called when no messages have been received during specified ReadTimeout wait time. It should be safe for concurrent use.
  • ConnectionClosedHandler - is called when connection is closed by us, by server or there were errors during network read/write that led to connection closure
  • ErrorHandler - is called with the error when connection fails to perform some operation. In some cases instance of a SafeError will be passed to prevent data leaks (detalis)

If you want to override default options, you can do this when creating instance of a client or setting it separately using SetOptions(options...) method.

pingHandler := func(c *connection.Connection) {
	// send ping/heartbeat message like this
	ping := iso8583.NewMessage(brandSpec)
	// set other fields
	response, err := c.Send(ping)
	// handle error
}

inboundMessageHandler := func(c *connection.Connection, message *iso8583.Message) {
	// log received message or send a reply like this
	mti, err := message.GetMTI()
	// handle err

	// implement logic for network management messages
	switch mti {
	case "0800":
		echo := iso8583.NewMessage(brandSpec)
		echo.MTI("0810")
		// set other fields
		err := c.Reply(echo)
		// handle error
	default:
		// log unrecognized message
	}
}

c, err := connection.New("127.0.0.1:9999", brandSpec, readMessageLength, writeMessageLength,
	connection.SendTimeout(100*time.Millisecond),
	connection.IdleTime(50*time.Millisecond),
	connection.PingHandler(pingHandler),
	connection.InboundMessageHandler(inboundMessageHandler),
)

// work with the client
Handler invocation during the connection life cycle

This section explains the various stages at which different handler functions are triggered throughout the lifecycle of the Connection.

On connection establishment:
  • OnConnect or OnConnectCtx: This handler is invoked immediately after the TCP connection is made. It can be utilized for operations that should be performed before the connection is officially considered established (e.g., sending SignOn message and receiving its response). NOTE If both OnConnect and OnConnectCtx are defined, OnConnectCtx will be used.

  • ConnectionEstablishedHandler (async): This asynchronous handler is triggered when the connection is logically considered established.

On error occurrence:
  • ErrorHandler (async): This asynchronous handler is executed when an error occurs during message reading or writing.
On message receipt:
  • InboundMessageHandler (async): This asynchronous handler is triggered when an incoming message is received, or a received message does not have a matching request (this can happen when we return an error for the Send method after a timeout and then, subsequently, receive a response, aka late response).
On read timeout:
  • ReadTimeoutHandler (async): This asynchronous handler is activated when no messages are received within the set ReadTimeout period.
On idle time:
  • PingHandler (async): This asynchronous handler is invoked when no messages are sent within the IdleTime.
On connection closure:
  • ConnectionClosedHandlers (async): These asynchronous handlers are invoked after connection is closed by us, by the server or due to the network errors

  • OnClose or OnCloseCtx: This handler is activated before the connection is closed when we manually close the connection. NOTE If both OnClose and OnCloseCtx are defined, OnCloseCtx will be used.

(m)TLS connection

Configure to use TLS during connect:

c, err := connection.New("127.0.0.1:443", testSpec, readMessageLength, writeMessageLength,
	// if server requires client certificate (mTLS)
	connection.ClientCert("./testdata/client.crt", "./testdata/client.key"),
	// if you use a self signed certificate, provide root certificate
	connection.RootCAs("./testdata/ca.crt"),
)
// handle error

Usage

// see configuration options for more details
c, err := connection.New("127.0.0.1:9999", brandSpec, readMessageLength, writeMessageLength,
	connection.SendTimeout(100*time.Millisecond),
	connection.IdleTime(50*time.Millisecond),
	connection.PingHandler(pingHandler),
	connection.UnmatchedMessageHandler(unmatchedMessageHandler),
	connection.ConnectionClosedHandler(connectionClosedHandler),
)
err := c.Connect()
if err != nil {
	// handle error
}
defer c.Close()

// create iso8583 message
message := iso8583.NewMessage(brandSpec)
message.MTI("0800")
// ...

// send message to the server
response, err := connection.Send(message)
if err != nil {
	// handle error
}

// work with the response
mti, err := response.GetMTI()
if err != nil {
	// handle error
}

if mti != "0810" {
	// handle error
}

Connection Pool

Sometimes you want to establish multiple connections and re-create them when such connections are closed due to a network errors. Connection Pool is really helpful for such use cases.

To use Pool, first, you need to create a factory function that knows how to create connections and a list of addresses you want to establish connections with. You can establish connections with different or the same addresses.

// Factory method that will build connection
factory := func(addr string) (*connection.Connection, error) {
	c, err := connection.New(
		addr,
		testSpec,
		readMessageLength,
		writeMessageLength,
		// set shot connect timeout so we can test re-connects
		connection.ConnectTimeout(500*time.Millisecond),
		connection.OnConnect(func(c *connection.Connection) {
			c.Set("status", "online")
		}),
	)
	if err != nil {
		return nil, fmt.Errorf("building iso8583 connection: %w", err)
	}

	return c, nil
}

if there is a need to apply address specific configurations like TLS, you can create a map or function that will return all needed options for the address:

func getAddrOpts(addr string) []Option {
	switch addr {
	case "127.0.0.1":
		return []Option{
			connection.ClientCert(certA, keyA),
		}
	case "127.0.0.2":
		return []Option{
			connection.ClientCert(certB, keyB),
		}
	}
}

factory := func(addr string) (*connection.Connection, error) {
	c, err := connection.New(
		addr,
		testSpec,
		readMessageLength,
		writeMessageLength,
		connection.ConnectTimeout(500*time.Millisecond),
		getAddrOpts(addr)...,
	)
	if err != nil {
		return nil, fmt.Errorf("building iso8583 connection: %w", err)
	}

	return c, nil
}

Now you can create pool and establish all connections:

// let's say we want Get() to return only online connections
filterOnlineConnections := func(conn *connection.Connection) bool {
	return conn.Get("status") == "online"
}

pool, err := connection.NewPool(
	factory,
	addrs,
	connection.PoolConnectionsFilter(filterOnlineConnections),
)
// handle error

err = pool.Connect()
// handle error

When pool is connected, you can get connection from the pool to send message to:

// get connection (only "online") from the pool
conn, err := pool.Get()
// handle err

// create iso8583 message
msg := iso8583.NewMessage(yourSpec)
// ...

reply, err := conn.Send(msg)
// handle error

Because Connection is safe to be used concurrently, you don't return connection back to the pool. But don't close the connection directly as the pool will remove it from the pool of connections only when connection is closed by the server. It does it using ConnectionClosedHandler.

Configuration of the Pool

Following options are supported:

  • ReconnectWait sets the time to wait after first re-connect attempt
  • MaxReconnectWait specifies the maximum duration to wait between reconnection attempts, serving as the upper bound for exponential backoff; if set to zero, there's no exponential backoff and ReconnectWait is used for each retry.
  • ErrorHandler is called in a goroutine with the errors that can't be returned to the caller (from other goroutines)
  • MinConnections is the number of connections required to be established when we connect the pool
  • ConnectionsFilter is a function to filter connections in the pool for Get, IsDegraded or IsUp methods

Context

You can provide context to the Connect and Close functions in addition to defining OnConnectCtx and OnCloseCtx in the connection options. This will allow you to pass along telemetry or any other information on contexts through from the Connect/Close calls to your handler functions:

c, err := connection.New("127.0.0.1:9999", brandSpec, readMessageLength, writeMessageLength,
	connection.SendTimeout(100*time.Millisecond),
	connection.IdleTime(50*time.Millisecond),
    connect.OnConnectCtx(func(ctx context.Context, c *connection.Connection){
        return signOnFunc(ctx, c)
    }),
    connect.OnCloseCtx(func(ctx context.Context, c *connection.Connection){
        return signOffFunc(ctx, c)
    }),
)

ctx := context.Background()
c.ConnectCtx(ctx)

...

c.CloseCtx(ctx)

Benchmark

To benchmark the connection, we created a test server that sends a response to each request. Therefore, the benchmark measures the time it takes to send a message and receive a response by both the client and the server. If you are looking to measure client performance only, you should either run the test server on a separate machine, or, with some approximation, you can multiply the results by 2.

For the connection benchmark, we pack/unpack an ISO 8583 message with only 2 fields: MTI and STAN.

We have two types of benchmarks: BenchmarkParallel and BenchmarkProcess.

BenchmarkParallel uses b.N goroutines to send (and receive) messages to the server. You can set the number of goroutines using the -cpu flag. Please note that the -cpu flag also sets GOMAXPROCS.

For example, to run the benchmark with 6 goroutines/CPUs/cores, use the following command:

go test -bench=BenchmarkParallel -cpu=6

Be aware that results may vary depending on the number of actual CPUs, cores, throttling, and system load.

Here is the result on MacBook Pro:

➜ go test -bench=BenchmarkParallel -cpu 6
goos: darwin
goarch: amd64
pkg: github.com/moov-io/iso8583-connection
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkParallel-6        63703             18849 ns/op
PASS
ok      github.com/moov-io/iso8583-connection   26.079s

It shows that 53K messages were sent and recieved by both client and server in 1sec.

BenchmarkProcessNNN, where NNN is the number of messages to send, is another type of benchmark. In this benchmark, the we send and receive messages to the server concurrently by running NNN goroutines.

To run such benchmarks, use:

go test -bench=BenchmarkProcess

Here are the latest results on MacBook Pro:

➜ go test -bench=BenchmarkProcess -cpu 6
goos: darwin
goarch: amd64
pkg: github.com/moov-io/iso8583-connection
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkProcess100-6                732           1579450 ns/op
BenchmarkProcess1000-6                75          15220504 ns/op
BenchmarkProcess10000-6                7         149483539 ns/op
BenchmarkProcess100000-6               1        1681237716 ns/op
PASS
ok      github.com/moov-io/iso8583-connection   29.967s

It shows that:

  • The time taken scales approximately linearly with the number of messages processed.
  • 1.681 seconds to send/receive 100,000 messages by both client and server.
  • 149.48 milliseconds to send/receive 10,000 messages by both client and server.
  • 15.22 milliseconds to send/receive 1,000 messages by both client and server.
  • 1.579 milliseconds to send/receive 100 messages by both client and server.

License

Apache License 2.0 - See LICENSE for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrConnectionClosed = errors.New("connection closed")
	ErrSendTimeout      = errors.New("message send timeout")
)
View Source
var ErrNoConnections = errors.New("no connections (online)")

Functions

This section is empty.

Types

type Connection

type Connection struct {
	Opts Options
	// contains filtered or unexported fields
}

Connection represents an ISO 8583 Connection. Connection may be used by multiple goroutines simultaneously.

func New

func New(addr string, spec *iso8583.MessageSpec, mlReader MessageLengthReader, mlWriter MessageLengthWriter, options ...Option) (*Connection, error)

New creates and configures Connection. To establish network connection, call `Connect()`.

func NewFrom

func NewFrom(conn io.ReadWriteCloser, spec *iso8583.MessageSpec, mlReader MessageLengthReader, mlWriter MessageLengthWriter, options ...Option) (*Connection, error)

NewFrom accepts conn (net.Conn, or any io.ReadWriteCloser) which will be used as a transport for the returned Connection. Returned Connection is ready to be used for message sending and receiving

func (*Connection) Addr added in v0.1.6

func (c *Connection) Addr() string

Addr returns the remote address of the connection

func (*Connection) Close

func (c *Connection) Close() error

Close waits for pending requests to complete and then closes network connection with ISO 8583 server

func (*Connection) CloseCtx added in v0.8.1

func (c *Connection) CloseCtx(ctx context.Context) error

CloseCtx waits for pending requests to complete and then closes network connection with ISO 8583 server

func (*Connection) Connect

func (c *Connection) Connect() error

Connect establishes the connection to the server using configured Addr

func (*Connection) ConnectCtx added in v0.8.1

func (c *Connection) ConnectCtx(ctx context.Context) error

ConnectCtx establishes the connection to the server using configured Addr

func (*Connection) Done

func (c *Connection) Done() <-chan struct{}

func (*Connection) RejectMessage added in v0.8.0

func (c *Connection) RejectMessage(rejectedMessage *iso8583.Message, rejectionError error) error

RejectMessage returns RejectedMessageError to the response err channel that corresponds to the ID of the rejectedMessage. This method is used to reject messages that were sent to the network and response was received, but response code indicates that message was rejected. In many cases, such rejection happens outside of normal request-response flow, so it is not possible to return response to the caller. In such cases, RejectedMessageError is returned. It's up to the implementation to decide when to call RejectMessage and when to return RejectedMessageError.

func (*Connection) Reply

func (c *Connection) Reply(message *iso8583.Message) error

Reply sends the message and does not wait for a reply to be received. Any reply received for message send using Reply will be handled with unmatchedMessageHandler

func (*Connection) Send

func (c *Connection) Send(message *iso8583.Message, options ...Option) (*iso8583.Message, error)

Send sends message and waits for the response. You can pass optional parameters to the Send method using functional options pattern. Currently, only SendTimeout option is supported. Using it, you can set specific send timeout value for the `Send` method call. Example:

conn.Send(msg, connection.SendTimeout(5 * time.Second))

func (*Connection) SetOptions

func (c *Connection) SetOptions(options ...Option) error

SetOptions sets connection options

func (*Connection) SetStatus added in v0.3.0

func (c *Connection) SetStatus(status Status)

SetStatus sets the connection status

func (*Connection) Status added in v0.3.0

func (c *Connection) Status() Status

Status returns the connection status

func (*Connection) Write added in v0.5.0

func (c *Connection) Write(p []byte) (int, error)

Write writes data directly to the connection. It is crucial to note that the Write operation is atomic in nature, meaning it completes in a single uninterrupted step. When writing data, the entire message—including its header and any other components—should be written in one go. Splitting a single message into multiple Write calls is dangerous, as it could lead to unexpected behavior or errors.

type ConnectionFactoryFunc added in v0.3.0

type ConnectionFactoryFunc func(addr string) (*Connection, error)

type FilterFunc added in v0.3.0

type FilterFunc func(*Connection) bool

FilterFunc is a function to filter connections

type MessageLengthReader

type MessageLengthReader func(r io.Reader) (int, error)

MessageLengthReader reads message header from the r and returns message length

type MessageLengthWriter

type MessageLengthWriter func(w io.Writer, length int) (int, error)

MessageLengthWriter writes message header with encoded length into w

type MessageReader added in v0.4.0

type MessageReader interface {
	ReadMessage(r io.Reader) (*iso8583.Message, error)
}

type MessageWriter added in v0.4.0

type MessageWriter interface {
	WriteMessage(w io.Writer, message *iso8583.Message) error
}

type Option

type Option func(*Options) error

func ClientCert

func ClientCert(cert, key string) Option

func ConnectTimeout added in v0.1.6

func ConnectTimeout(d time.Duration) Option

ConnectTimeout sets an SendTimeout option

func ConnectionClosedHandler added in v0.1.3

func ConnectionClosedHandler(handler func(c *Connection)) Option

ConnectionClosedHandler sets a ConnectionClosedHandler option

func ConnectionEstablishedHandler added in v0.3.0

func ConnectionEstablishedHandler(handler func(c *Connection)) Option

func ErrorHandler added in v0.1.5

func ErrorHandler(h func(err error)) Option

ErrorHandler sets an ErrorHandler option in many cases err will be an instance of the `SafeError` for more details: https://github.com/moov-io/iso8583/pull/185

func IdleTime

func IdleTime(d time.Duration) Option

IdleTime sets an IdleTime option

func InboundMessageHandler

func InboundMessageHandler(handler func(c *Connection, message *iso8583.Message)) Option

InboundMessageHandler sets an InboundMessageHandler option

func OnClose added in v0.3.1

func OnClose(h func(c *Connection) error) Option

func OnCloseCtx added in v0.8.1

func OnCloseCtx(h func(ctx context.Context, c *Connection) error) Option

func OnConnect added in v0.3.0

func OnConnect(h func(c *Connection) error) Option

OnConnect sets a callback that will be synchronously called when connection is established. If it returns error, then connections will be closed and re-connect will be attempted

func OnConnectCtx added in v0.8.1

func OnConnectCtx(h func(ctx context.Context, c *Connection) error) Option

OnConnectCtx sets a callback that will be synchronously called when connection is established. If it returns error, then connections will be closed and re-connect will be attempted

func PingHandler

func PingHandler(handler func(c *Connection)) Option

PingHandler sets a PingHandler option

func ReadTimeout added in v0.1.4

func ReadTimeout(d time.Duration) Option

ReadTimeout sets an ReadTimeout option

func ReadTimeoutHandler added in v0.1.4

func ReadTimeoutHandler(handler func(c *Connection)) Option

ReadTimeoutHandler sets a ReadTimeoutHandler option

func RootCAs

func RootCAs(file ...string) Option

RootCAs creates pool of Root CAs

func SendTimeout

func SendTimeout(d time.Duration) Option

SendTimeout sets an SendTimeout option

func SetMessageReader added in v0.4.0

func SetMessageReader(r MessageReader) Option

SetMessageReader sets a MessageReader option

func SetMessageWriter added in v0.4.0

func SetMessageWriter(w MessageWriter) Option

SetMessageWriter sets a MessageWriter option

func SetRequestIDGenerator added in v0.3.2

func SetRequestIDGenerator(g RequestIDGenerator) Option

RequestIDGenerator sets a RequestIDGenerator option

func SetTLSConfig

func SetTLSConfig(cfg func(*tls.Config)) Option

type Options

type Options struct {
	// ConnectTimeout sets the timeout for establishing new connections.
	// The default is 10 seconds.
	ConnectTimeout time.Duration

	// SendTimeout sets the timeout for a Send operation.
	// The default is 30 seconds.
	SendTimeout time.Duration

	// IdleTime is the period at which the client will be sending ping
	// message to the server.
	// The default is 5 seconds.
	IdleTime time.Duration

	// ReadTimeout is the maximum time between read events before the
	// ReadTimeoutHandler is called.
	// The default is 60 seconds.
	ReadTimeout time.Duration

	// PingHandler is called when no message was sent during idle time
	// it should be safe for concurrent use
	PingHandler func(c *Connection)

	// ReadTimeoutHandler is called when no message has been received within
	// the ReadTimeout interval
	ReadTimeoutHandler func(c *Connection)

	// InboundMessageHandler is called when a message from the server is
	// received and no matching request for it was found.
	// InboundMessageHandler should be safe for concurrent use. Use it
	// for the following use cases:
	// * to log timed out responses
	// * to handle network management messages (echo, heartbeat, etc.)
	InboundMessageHandler func(c *Connection, message *iso8583.Message)

	// ConnectionClosedHandlers is called after connection is closed by us,
	// by the server or when there are network errors during network
	// read/write
	ConnectionClosedHandlers []func(c *Connection)

	// ConnectionEstablishedHandler is called when connection is
	// established with the server
	ConnectionEstablishedHandler func(c *Connection)

	TLSConfig *tls.Config

	// ErrorHandler is called in a goroutine with the errors that can't be
	// returned to the caller
	ErrorHandler func(err error)

	// If both OnConnect and OnConnectCtx are set, OnConnectCtx will be used
	// OnConnect is called synchronously when a connection is established
	OnConnect func(c *Connection) error

	// OnConnectCtx is called synchronously when a connection is established
	OnConnectCtx func(ctx context.Context, c *Connection) error

	// If both OnClose and OnCloseCtx are set, OnCloseCtx will be used
	// OnClose is called synchronously before a connection is closed
	OnClose func(c *Connection) error

	// OnCloseCtx is called synchronously before a connection is closed
	OnCloseCtx func(ctx context.Context, c *Connection) error

	// RequestIDGenerator is used to generate a unique identifier for a request
	// so that responses from the server can be matched to the original request.
	RequestIDGenerator RequestIDGenerator

	// MessageReader is used to read a message from the connection
	// if set, connection's MessageLengthReader will be ignored
	MessageReader MessageReader

	// MessageWriter is used to write a message to the connection
	// if set, connection's MessageLengthWriter will be ignored
	MessageWriter MessageWriter
}

func GetDefaultOptions

func GetDefaultOptions() Options

type Pool added in v0.3.0

type Pool struct {
	Factory ConnectionFactoryFunc
	Addrs   []string
	Opts    PoolOptions
	// contains filtered or unexported fields
}

func NewPool added in v0.3.0

func NewPool(factory ConnectionFactoryFunc, addrs []string, options ...PoolOption) (*Pool, error)

Pool - provides connections to the clients. It removes the connection from the pool if it was closed and in the background tries to create and etablish new connection so the pool will be full.

func (*Pool) Close added in v0.3.0

func (p *Pool) Close() error

Close closes all connections in the pool

func (*Pool) CloseCtx added in v0.8.1

func (p *Pool) CloseCtx(ctx context.Context) error

CloseCtx closes all connections in the pool

func (*Pool) Connect added in v0.3.0

func (p *Pool) Connect() error

Connect creates poll of connections by calling Factory method and connect them all

func (*Pool) ConnectCtx added in v0.8.1

func (p *Pool) ConnectCtx(ctx context.Context) error

Connect creates poll of connections by calling Factory method and connect them all

func (*Pool) Connections added in v0.3.0

func (p *Pool) Connections() []*Connection

Connections returns copy of all connections from the pool

func (*Pool) Done added in v0.3.0

func (p *Pool) Done() <-chan struct{}

func (*Pool) Get added in v0.3.0

func (p *Pool) Get() (*Connection, error)

Get returns filtered connection from the pool

func (*Pool) IsDegraded added in v0.3.0

func (p *Pool) IsDegraded() bool

IsDegraded returns true if pool is not full

func (*Pool) IsUp added in v0.3.0

func (p *Pool) IsUp() bool

IsUp returns true if at least one connection is in the pool

type PoolOption added in v0.3.0

type PoolOption func(*PoolOptions) error

func PoolConnectionsFilter added in v0.3.0

func PoolConnectionsFilter(f func(*Connection) bool) PoolOption

func PoolErrorHandler added in v0.3.0

func PoolErrorHandler(h func(err error)) PoolOption

func PoolMaxReconnectWait added in v0.6.0

func PoolMaxReconnectWait(rw time.Duration) PoolOption

func PoolMinConnections added in v0.3.0

func PoolMinConnections(n int) PoolOption

func PoolReconnectWait added in v0.3.0

func PoolReconnectWait(rw time.Duration) PoolOption

type PoolOptions added in v0.3.0

type PoolOptions struct {
	// ReconnectWait sets the time to wait after first re-connect attempt
	// The default is 5 seconds
	ReconnectWait time.Duration

	// MaxReconnectWait specifies the maximum duration to wait between
	// reconnection attempts, serving as the upper bound for exponential
	// backoff.
	// A zero value means no exponential backoff and ReconnectWait is used
	// for each retry.
	// The default is 0.
	MaxReconnectWait time.Duration

	// ErrorHandler is called in a goroutine with the errors that can't be
	// returned to the caller. Don't block in this function as it will
	// block the connection pool Close() method.
	ErrorHandler func(err error)

	// MinConnections is the number of connections required to be established when
	// we connect the pool.
	// A zero value means that Pool will not return error on `Connect` and will
	// try to connect to all the addresses in the pool.
	// The default is 1.
	MinConnections int

	// ConnectionsFilter is a function to filter connections in the pool
	// when Get() is called
	ConnectionsFilter func(*Connection) bool
}

func GetDefaultPoolOptions added in v0.3.0

func GetDefaultPoolOptions() PoolOptions

type RejectedMessageError added in v0.8.0

type RejectedMessageError struct {
	Err error
}

RejectedMessageError is returned to the `Send` method caller when message is rejected.

func (*RejectedMessageError) Error added in v0.8.0

func (e *RejectedMessageError) Error() string

func (*RejectedMessageError) Unwrap added in v0.8.0

func (e *RejectedMessageError) Unwrap() error

type RequestIDGenerator added in v0.3.2

type RequestIDGenerator interface {
	GenerateRequestID(msg *iso8583.Message) (string, error)
}

RequestIDGenerator is an interface that generates a unique identifier for a request so that responses from the server can be matched to the original request.

type Status added in v0.3.0

type Status string

ConnectionStatus

const (
	// StatusOnline means connection is online
	StatusOnline Status = "online"

	// StatusOffline means connection is offline
	StatusOffline Status = "offline"

	// StatusUnknown means connection status is unknown (not set)
	StatusUnknown Status = ""
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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