Documentation
¶
Overview ¶
Package session provides server middleware and reference implementations for Flight session management.
For more details on the Flight Session Specification, see: https://arrow.apache.org/docs/format/FlightSql.html#flight-server-session-management
NewServerSessionMiddleware manages sessions using cookies, so any client would need its own middleware/support for storing and sending those cookies. The cookies may be stateful or stateless:
NewStatefulServerSessionManager implements stateful cookies.
NewStatelessServerSessionManager implements stateless cookies.
See details of either implementation for caveats and recommended usage scenarios.
Example (CustomStatefulMiddleware) ¶
package main
import (
"github.com/apache/arrow-go/v18/arrow/flight/session"
"github.com/google/uuid"
)
func main() {
// Generate IDs for new sessions using provided function
factory := session.NewSessionFactory(uuid.NewString)
// Create a SessionStore to persist sessions.
// In-memory store is default; you may provide your own implementation.
store := session.NewSessionStore()
// Construct the middleware with the custom manager.
manager := session.NewStatefulServerSessionManager(session.WithFactory(factory), session.WithStore(store))
middleware := session.NewServerSessionMiddleware(manager)
_ = middleware // ... remaining setup is the same as DefaultMiddleware example
}
Example (DefaultMiddleware) ¶
package main
import (
"log"
"github.com/apache/arrow-go/v18/arrow/flight"
"github.com/apache/arrow-go/v18/arrow/flight/flightsql"
"github.com/apache/arrow-go/v18/arrow/flight/session"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func main() {
// Setup server with default session middleware
middleware := session.NewServerSessionMiddleware(nil)
srv := flight.NewServerWithMiddleware([]flight.ServerMiddleware{
flight.CreateServerMiddleware(middleware),
})
srv.RegisterFlightService(flightsql.NewFlightServer(&flightsql.BaseServer{}))
srv.Init("localhost:0")
go srv.Serve()
defer srv.Shutdown()
// Client will require cookie middleware in order to handle cookie-based server sessions
client, err := flightsql.NewClient(
srv.Addr().String(),
nil,
[]flight.ClientMiddleware{
flight.NewClientCookieMiddleware(),
},
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
log.Fatal(err)
}
defer client.Close()
}
Example (StatelessMiddleware) ¶
package main
import (
"github.com/apache/arrow-go/v18/arrow/flight/session"
)
func main() {
// Construct the middleware with the stateless manager.
manager := session.NewStatelessServerSessionManager()
middleware := session.NewServerSessionMiddleware(manager)
_ = middleware // ... remaining setup is the same as DefaultMiddleware example
}
Index ¶
- Constants
- Variables
- func CreateCookieForSession(session ServerSession) (http.Cookie, error)
- func GetIncomingCookieByName(ctx context.Context, name string) (http.Cookie, error)
- func NewServerSessionMiddleware(manager ServerSessionManager) *serverSessionMiddleware
- func NewSessionContext(ctx context.Context, session ServerSession) context.Context
- func NewSessionFactory(generateID func() string) *sessionFactory
- func NewSessionStore() *sessionStore
- func NewStatefulServerSessionManager(opts ...StatefulSessionManagerOption) *statefulServerSessionManager
- func NewStatelessServerSession(options map[string]*flight.SessionOptionValue) *statelessServerSession
- func NewStatelessServerSessionManager() *statelessServerSessionManager
- type ServerSession
- type ServerSessionManager
- type SessionFactory
- type SessionStore
- type StatefulSessionManagerOption
Examples ¶
Constants ¶
const StatefulSessionCookieName string = "arrow_flight_session_id"
const StatelessSessionCookieName string = "arrow_flight_session"
Variables ¶
var ErrNoSession error = errors.New("flight: server session not present")
Functions ¶
func CreateCookieForSession ¶
func CreateCookieForSession(session ServerSession) (http.Cookie, error)
func GetIncomingCookieByName ¶
func NewServerSessionMiddleware ¶
func NewServerSessionMiddleware(manager ServerSessionManager) *serverSessionMiddleware
NewServerSessionMiddleware creates new instance of CustomServerMiddleware implementing server session persistence.
The provided manager can be used to customize session implementation/behavior. If no manager is provided, a stateful in-memory, goroutine-safe implementation is used.
func NewSessionContext ¶
func NewSessionContext(ctx context.Context, session ServerSession) context.Context
NewSessionContex returns a copy of the provided context containing the provided ServerSession
func NewSessionFactory ¶
func NewSessionFactory(generateID func() string) *sessionFactory
NewSessionFactory creates a new SessionFactory, producing in-memory, goroutine-safe ServerSessions. The provided function MUST produce collision-free identifiers.
func NewSessionStore ¶
func NewSessionStore() *sessionStore
NewSessionStore creates a simple in-memory, goroutine-safe SessionStore
func NewStatefulServerSessionManager ¶
func NewStatefulServerSessionManager(opts ...StatefulSessionManagerOption) *statefulServerSessionManager
NewStatefulServerSessionManager creates a new ServerSessionManager.
- If unset via options, the default factory produces sessions with UUIDs.
- If unset via options, sessions are stored in-memory.
func NewStatelessServerSession ¶
func NewStatelessServerSession(options map[string]*flight.SessionOptionValue) *statelessServerSession
NewStatelessServerSession creates a new instance of a server session that can serialize its entire state. A map is provided containing the initial state. If it is nil, a new empty state will be created.
func NewStatelessServerSessionManager ¶
func NewStatelessServerSessionManager() *statelessServerSessionManager
NewStatelessServerSessionManager creates a new StatelessServerSessionManager.
The tokens it produces contain the entire session state, so sessions can be maintained across multiple backends. Token contents are considered opaque but are NOT encrypted.
Types ¶
type ServerSession ¶
type ServerSession interface {
// An identifier for the session that the server can use to reconstruct
// the session state on future requests. It is the responsibility of
// each implementation to define the token's semantics.
Token() string
// Get session option value by name, or nil if it does not exist
GetSessionOption(name string) *flight.SessionOptionValue
// Get a copy of the session options
GetSessionOptions() map[string]*flight.SessionOptionValue
// Set session option by name to given value
SetSessionOption(name string, value *flight.SessionOptionValue)
// Idempotently remove name from this session
EraseSessionOption(name string)
// Close the session
Close() error
// Report whether the session has been closed
Closed() bool
}
ServerSession is a container for named SessionOptionValues
func GetSessionFromContext ¶
func GetSessionFromContext(ctx context.Context) (ServerSession, error)
GetSessionFromContext retrieves the ServerSession from the provided context if it exists. An error indicates that the session was not found in the context.
type ServerSessionManager ¶
type ServerSessionManager interface {
// Create a new, empty ServerSession
CreateSession(ctx context.Context) (ServerSession, error)
// Get the current ServerSession, if one exists
GetSession(ctx context.Context) (ServerSession, error)
// Cleanup any resources associated with the current ServerSession
CloseSession(session ServerSession) error
}
ServerSessionManager handles session lifecycle management
type SessionFactory ¶
type SessionFactory interface {
// Create a new, empty ServerSession
CreateSession() (ServerSession, error)
}
SessionFactory creates ServerSession instances
type SessionStore ¶
type SessionStore interface {
// Get the session with the provided ID
Get(id string) (ServerSession, error)
// Persist the provided session
Put(session ServerSession) error
// Remove the session with the provided ID
Remove(id string) error
}
SessionStore handles persistence of ServerSession instances for stateful session implementations.
type StatefulSessionManagerOption ¶
type StatefulSessionManagerOption func(*statefulServerSessionManager)
func WithFactory ¶
func WithFactory(factory SessionFactory) StatefulSessionManagerOption
WithFactory specifies the SessionFactory to use for session creation
func WithStore ¶
func WithStore(store SessionStore) StatefulSessionManagerOption
WithStore specifies the SessionStore to use for session persistence