Skip to content
This repository has been archived by the owner on Jun 26, 2023. It is now read-only.

Commit

Permalink
switch to storing sessions in the context
Browse files Browse the repository at this point in the history
This patch allows associating a "session key" with a context by calling
`NewSession(ctx)`. When the session is used in a request, the exchange can call
`GetSession(ctx)` to make the request in the appropriate session, or create a
new session with the given session key.

Implements ipfs/kubo#7198
  • Loading branch information
Stebalien committed Apr 23, 2020
1 parent a30d3ce commit 711263a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ require (
github.com/ipfs/go-block-format v0.0.2
github.com/ipfs/go-cid v0.0.5
)

go 1.13
46 changes: 46 additions & 0 deletions interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,49 @@ type SessionExchange interface {
Interface
NewSession(context.Context) Fetcher
}

// SessionKey is an opaque type uniquely identifying a session. Each SessionKey
// should be allocated with new(SessionKey).
type SessionKey struct {
// Needs to be at least 1 byte wide to guarantee a unique memory address
// We could consider putting, e.g., a description/name here in the
// future.
_ byte
}

type sessionContextKey struct{}
type sessionContextValue struct {
sesKey *SessionKey
sesCtx context.Context
}

// NewSession registers a new session with the context. The session will be
// closed when the passed-in context is canceled.
//
// If there's already a session associated with the context, the existing
// session will be used.
//
// This function does not initialize any state, it just creates a new
// *SessionKey and associates it with the context.
func NewSession(ctx context.Context) context.Context {
if _, ok := ctx.Value(sessionContextKey{}).(*sessionContextValue); ok {
// Leave the session alone.
return ctx
}
return context.WithValue(ctx, sessionContextKey{}, &sessionContextValue{
sesKey: new(SessionKey),
sesCtx: ctx, // save this so we can construct the session with the _session_ context.
})
}

// GetSession loads the fetcher from the context. The returned context is the
// context associated with the session itself.
//
// If there is no session associated with this context, this function returns
// a new session key and the passed-in context.
func GetSession(ctx context.Context) (*SessionKey, context.Context) {
if s, ok := ctx.Value(sessionContextKey{}).(*sessionContextValue); ok {
return s.sesKey, s.sesCtx
}
return new(SessionKey), ctx
}

0 comments on commit 711263a

Please sign in to comment.