Documentation ¶
Overview ¶
Package gtcp is a TCP server framework that inherits battle-tested code from net/http and can be extended through built-in interfaces.
### Features
- Can be used in the same manner with http.Server(>= 1.8).
- Make API as much compatible as possible.
- Make the zero value useful.
- Inherits as much battle tested code from net/http.
- Provides much flexiblity through built-in interfaces.
- ConnHandler
- ConnHandler
- KeepAliveHandler that makes it easy to implement keepalive.
- PipelineHandler that makes it easy to implement pipelining.
- ConnTracker
- MapConnTracker that handles force closing active connections also graceful shutdown.
- WGConnTracker that handles only graceful shutdown using a naive way with sync.WaitGroup.
- Conn
- BufferedConn that wraps Conn in bufio.Reader/Writer.
- StatsConn that wraps Conn to measure incomming/outgoing bytes.
- DebugConn that wraps Conn to output debug information.
- Logger
- BuiltinLogger that logs using standard log package.
- Retry
- ExponentialRetry that implements exponential backoff algorithm without jitter.
- Statistics
- TrafficStatistics that measures incomming/outgoing traffic across a server.
- Limiter
- MaxConnLimiter that limits connections based on the maximum number.
- Gets GC pressure as little as possible with sync.Pool.
- Zero 3rd party depentencies.
### TODO
- Support TLS
- Support multiple listeners
Index ¶
- Variables
- func ListenAndServe(addr string, handler ConnHandler) error
- type BufferedConn
- type BuiltinLogger
- type Conn
- type ConnHandler
- type ConnTracker
- type DebugConn
- type ExponentialRetry
- type Limiter
- type Logger
- type MapConnTracker
- type MaxConnLimiter
- type NewConn
- type PipelineReader
- type PipelineWriter
- type ReqHandler
- type Retry
- type Server
- func (s *Server) Close() (err error)
- func (s *Server) ListenAndServe() error
- func (s *Server) ListenerAddr() net.Addr
- func (s *Server) Serve(l net.Listener) error
- func (s *Server) SetKeepAliveHandler(idle time.Duration, h ReqHandler)
- func (s *Server) SetPipelineHandler(numBuf int, pr PipelineReader, pw PipelineWriter)
- func (s *Server) Shutdown(ctx context.Context) (err error)
- type Statistics
- type StatsConn
- type TrafficStatistics
- type WGConnTracker
- type WriteFlusher
Constants ¶
This section is empty.
Variables ¶
var ( // ErrServerClosed returned when listener got closed through Close/Shutdown. ErrServerClosed = errors.New("gtcp: Server closed") // ErrAbortHandler is a sentinel panic value to abort a handler. // panicking with ErrAbortHandler also suppresses logging of a stack // trace to the server's error log. ErrAbortHandler = errors.New("gtcp: abort Handler") )
var ( // ErrBufferFull returned when Peek takes a larger value than its buffer. ErrBufferFull = errors.New("gtcp: buffer full") )
Functions ¶
func ListenAndServe ¶
func ListenAndServe(addr string, handler ConnHandler) error
ListenAndServe listens on the TCP network address addr and then calls Serve to handle requests on incoming connections. ListenAndServe always returns a non-nil error.
Types ¶
type BufferedConn ¶
type BufferedConn struct { Conn // contains filtered or unexported fields }
BufferedConn implements Conn that wraps Conn in bufio.Reader|Writer.
func (*BufferedConn) Close ¶
func (b *BufferedConn) Close() (err error)
Close closes the internal bufio.Reader|Writer and also Conn. It's protected by sync.Once as multiple goroutines can call especially in case using gtcp.Server.Close|Shutdown.
func (*BufferedConn) Flush ¶
func (b *BufferedConn) Flush() (err error)
Flush writes any buffered data to the underlying Conn.
func (*BufferedConn) Peek ¶
func (b *BufferedConn) Peek(n int) ([]byte, error)
Peek returns the next n bytes without advancing the reader.
type BuiltinLogger ¶
type BuiltinLogger struct{}
BuiltinLogger implements Logger based on the standard log package.
func (BuiltinLogger) Errorf ¶
func (l BuiltinLogger) Errorf(format string, args ...interface{})
Errorf logs error information using the standard log package.
type Conn ¶
type Conn interface { net.Conn // Flush writes any buffered data to the underlying net.Conn. Flush() error // SetCancelFunc sets context.CancelFunc that called automatically // when Read/Write failed. SetCancelFunc(context.CancelFunc) // Stats returns in/out bytes gone through this Conn. Stats() (int64, int64) // SetIdle sets whether this Conn is idle or not. // It's used to realize gtcp.Server.Shutdown. SetIdle(bool) // IsIdle returns whether this Conn is idle or not. // It's used to realize gtcp.Server.Shutdown. IsIdle() bool // Peek returns the next n bytes without advancing the reader. Peek(int) ([]byte, error) }
Conn is the interface that wraps connetcion specific operations in addition to net.Conn.
func NewBaseConn ¶
NewBaseConn takes net.Conn and returns Conn that wraps net.Conn. It's exported only for test purpose.
func NewBufferedConn ¶
NewBufferedConn returns Conn wraps a given Conn in bufio.Reader|Writer.
func NewDebugConn ¶
NewDebugConn returns Conn that logs debug information using standard log.
func NewStatsConn ¶
NewStatsConn returns Conn that holds in/out bytes.
type ConnHandler ¶
ConnHandler is the callback function called when Conn gets ready to communicate with peer. You can use ConnHandler to gain full control on socket.
type ConnTracker ¶
type ConnTracker interface { // AddConn adds Conn to active connections. AddConn(Conn) // DelConn deletes Conn from active connections. DelConn(Conn) // Close closes active connections with the same manner on net/http/Server.Close. // In short, force close. Close() error // Shutdown closes active connections with the same manner on net/http/Server.Shutdown. // In short, graceful shutdown. Shutdown(context.Context) error }
ConnTracker is the interface that wraps operations to track active connections.
func NewMapConnTracker ¶
func NewMapConnTracker() ConnTracker
NewMapConnTracker returns a new MapConnTracker as a ConnTracker.
type DebugConn ¶
type DebugConn struct {
Conn
}
DebugConn implements Conn that logs every Read/Write/Close operations using standard log.
func (*DebugConn) Close ¶
Close closes the internal Conn. It also outputs debug information before/after calling internal Conn.Close().
type ExponentialRetry ¶
type ExponentialRetry struct { // InitialDelay defines the retry interval at the first retry. InitialDelay time.Duration // MaxDelay defines the maximum retry interval. MaxDelay time.Duration }
ExponentialRetry implements exponential backoff algorithm without jitter.
type Limiter ¶
type Limiter interface { // OnConnected is called when Conn accepted on a listener. // Returns false if limits it otherwise true. OnConnected(Conn) bool // OnClosed is called when Conn closed. OnClosed(Conn) }
Limiter is the interface that limits connections accepted.
type Logger ¶
type Logger interface { // Errorf logs error information. // Arguments are handled in the manner of fmt.Printf. Errorf(format string, args ...interface{}) }
Logger is the interface that wraps logging operations.
var ( // DefaultLogger is the default Logger. DefaultLogger Logger = BuiltinLogger{} )
type MapConnTracker ¶
type MapConnTracker struct {
// contains filtered or unexported fields
}
MapConnTracker implements ConnTracker with the same manner on net/http/Server.
func (*MapConnTracker) AddConn ¶
func (ct *MapConnTracker) AddConn(conn Conn)
AddConn adds Conn to active connections using map.
func (*MapConnTracker) Close ¶
func (ct *MapConnTracker) Close() error
Close closes active connections forcefully.
func (*MapConnTracker) DelConn ¶
func (ct *MapConnTracker) DelConn(conn Conn)
DelConn deletes Conn from active connections using map.
func (*MapConnTracker) Shutdown ¶
func (ct *MapConnTracker) Shutdown(ctx context.Context) error
Shutdown closes active connections with the same manner on net/http/Server.Shutdown. It's useful when you use gtcp.Server.SetKeepAliveHandler or use ConnHandler directly with gtcp.Conn.(SetIdle|IsIdle) as Shutdown only try to close idle connections. If the provided context expires before the shutdown is complete, then the context's error is returned.
type MaxConnLimiter ¶
type MaxConnLimiter struct { // Max defines the maximum connections. Max uint32 // contains filtered or unexported fields }
MaxConnLimiter implements Limiter based on the maximum connections.
func (*MaxConnLimiter) OnClosed ¶
func (mc *MaxConnLimiter) OnClosed(conn Conn)
OnClosed decreases the number of current active connections.
func (*MaxConnLimiter) OnConnected ¶
func (mc *MaxConnLimiter) OnConnected(conn Conn) bool
OnConnected returns false if the number of current active connections exceeds Max, otherwise true.
type NewConn ¶
NewConn is the function that takes a Conn and returns another Conn that enables to generate multi layered Conn. ex)
func(conn Conn) Conn { return gtcp.NewBufferedConn(gtcp.NewStatsConn(conn)) }
type PipelineReader ¶
PipelineReader is the callback function used with SetPipelineHandler. SetPipelineHandler enables to implement protocol pipelining easily. It's used for reading part of pipelining and dispatch meaningful []byte to PipelineWriter via return value.
type PipelineWriter ¶
type PipelineWriter func([]byte, WriteFlusher) error
PipelineWriter is the callback function used with SetPipelineHandler. SetPipelineHandler enables to implement protocol pipelining easily. It's used for writing part of pipelining and called when receiving a meaningful []byte from PipelineReader.
type ReqHandler ¶
ReqHandler is the callback function used with SetKeepAliveHandler. It's called when Conn gets ready to communicate specifically - accepted by listener - receiving one more byte while being in keepalive You can use ReqHandler with SetKeepAliveHandler to implement keepalive easily.
type Retry ¶
Retry is the interface that provides a retry strategy based on a given retry counter.
var ( // DefaultRetry implements the same behaviour with net/http/Server DefaultRetry Retry = ExponentialRetry{ InitialDelay: 5 * time.Millisecond, MaxDelay: 1 * time.Second, } )
type Server ¶
type Server struct { // Addr to listen on, ":1979" if empty. Addr string // ConnHandler handles a tcp connection accepted. // It can be used not only directly setting ConnHandler but // - Server.SetKeepAliveHandler // - Server.SetPipelineHandler // Panic occurred if empty. ConnHandler ConnHandler // NewConn that applied to each tcp connection accepted by listener. // It can be // - gtcp.NewBufferedConn // - gtcp.NewStatsConn // - gtcp.NewDebugConn // also can be layered like the below. // func(conn Conn) Conn { // return gtcp.NewBufferedConn(gtcp.NewStatsConn(conn)) // } // None NewConn is applied if empty. NewConn NewConn // ConnTracker that handles active connections. // It can be // - gtcp.MapConnTracker // - gtcp.WGConnTracker // gtcp.MapConnTracker is set if empty. ConnTracker ConnTracker // Logger that logs if an error occurred in gtcp. // It can be // - gtcp.BuiltinLogger // gtcp.DefaultLogger is set if empty. Logger Logger // Retry that handles the retry interval when Accept on listner failed. // It can be // - gtcp.ExponentialRetry // gtcp.DefaultRetry is set if empty.(it behaves in the same manner with net/http/Server. Retry Retry // Limiters that limits connections. // It can be // - gtcp.MaxConnLimiter // also multiple limiters can be set. // None Limiter is set if empty. Limiters []Limiter // Statistics that measures some statistics. // It can be // - gtcp.TrafficStatistics // gtcp.TrafficStatistics is set if empty. Statistics Statistics // contains filtered or unexported fields }
Server defines parameters for running a gtcp server. The zero value for Server is a valid configuration.
func (*Server) Close ¶
Close immediately closes the listner and any connections tracked by ConnTracker. Close returns any error returned from closing the listner.
func (*Server) ListenAndServe ¶
ListenAndServe listens on the TCP network address Addr and then calls Serve to handle requests on incoming connections. If Addr is blank, ":1979" is used. ListenAndServe always returns a non-nil error.
func (*Server) ListenerAddr ¶
ListenerAddr returns the listner.Addr() or nil if listner is empty.
func (*Server) Serve ¶
Serve accepts incoming connections on the Listener l, creating a new service goroutine for each. The service goroutines call ConnHandler to reply to them.
func (*Server) SetKeepAliveHandler ¶
func (s *Server) SetKeepAliveHandler(idle time.Duration, h ReqHandler)
SetKeepAliveHandler enables to implement keepalive easily. It call h and call again repeatedly if receiving one more byte while waiting idle time or stop communicating. It also stop when detecting listener got closed.
func (*Server) SetPipelineHandler ¶
func (s *Server) SetPipelineHandler( numBuf int, pr PipelineReader, pw PipelineWriter)
SetPipelineHandler enables to implement protocol pipelining easily. It combines pr and pw with a buffered channel that has numBuf. pr need to implement reading part of pipelining and dispatch meaningful []byte to pw. pw need to implement writing part of pipelining. It stops if pr returns nil buf or any error. It also stop when detecting listener got closed.
type Statistics ¶
type Statistics interface { // AddConnStats adds a Conn statistics. AddConnStats(Conn) // Reset clears statistics holden now. Reset() // String returns a string that represents the current statistics. String() string }
Statistics is the interface that wraps operations for accumulating Conn statistics.
type StatsConn ¶
type StatsConn struct { Conn // InBytes stores incomming bytes. InBytes int64 // OutBytes stores outgoing bytes. OutBytes int64 }
StatsConn implements Conn that holds in/out bytes.
func (*StatsConn) Read ¶
Read reads data into buf and returns the number of bytes read into buf. It also adds InBytes and bytes read up.
type TrafficStatistics ¶
type TrafficStatistics struct {
// contains filtered or unexported fields
}
TrafficStatistics implements Statistics to hold the in/out traffic on a gtcp server.
func (*TrafficStatistics) AddConnStats ¶
func (ts *TrafficStatistics) AddConnStats(conn Conn)
AddConnStats ingests inBytes and outBytes from conn. You need to use StatsConn in gtcp.NewConn if you want in/out traffic.
func (*TrafficStatistics) Reset ¶
func (ts *TrafficStatistics) Reset()
Reset clears statistics holden now.
func (*TrafficStatistics) String ¶
func (ts *TrafficStatistics) String() (str string)
String returns the in/out traffic on a gtcp server as a json string.
type WGConnTracker ¶
type WGConnTracker struct {
// contains filtered or unexported fields
}
WGConnTracker implements ConnTracker with sync.WaitGroup. Its Close implemntation is semantically different from what ConnTracker.Close should be. Use MapConnTracker if you want force close active connections.
func (*WGConnTracker) AddConn ¶
func (ct *WGConnTracker) AddConn(Conn)
AddConn adds Conn to active connections using sync.WaitGroup.Add.
func (*WGConnTracker) Close ¶
func (ct *WGConnTracker) Close() error
Close closes(actually waits for get things done) active connections using sync.WaitGroup.Wait.
func (*WGConnTracker) DelConn ¶
func (ct *WGConnTracker) DelConn(Conn)
DelConn deletes Conn from active connections using sync.WaitGroup.Done.
type WriteFlusher ¶
type WriteFlusher interface { io.Writer // Flush writes any buffered data to the underlying Conn. Flush() error }
WriteFlusher is the interface that wraps write operations on Conn.