func (s *SessionInfo) GetRecreateToken() []byte {
	params := recreateSessionParams{
		Tasklist: s.tasklist,
	}
	return mustSerializeRecreateToken(&params)
}
GetRecreateToken returns the token needed to recreate a session. The returned value should be passed to
RecreateSession() API.
package internal
import (
	"context"
	"errors"
	"fmt"
	"sync"
	"time"
	"github.com/pborman/uuid"
	"go.uber.org/cadence/internal/common/backoff"
	"go.uber.org/zap"
)
type (
	SessionInfo struct {
		SessionID         string
		HostName          string
		resourceID        string  
		tasklist          string  
		sessionState      sessionState
		sessionCancelFunc CancelFunc  
		completionCtx     Context     
	}
	SessionOptions struct {
		ExecutionTimeout time.Duration
		CreationTimeout  time.Duration
		HeartbeatTimeout time.Duration
	}
	recreateSessionParams struct {
		Tasklist string
	}
	sessionState int
	sessionTokenBucket struct {
		*sync.Cond
		availableToken int
	}
	sessionEnvironment interface {
		CreateSession(ctx context.Context, sessionID string) (<-chan struct{}, error)
		CompleteSession(sessionID string)
		AddSessionToken()
		SignalCreationResponse(ctx context.Context, sessionID string) error
		GetResourceSpecificTasklist() string
		GetTokenBucket() *sessionTokenBucket
	}
	sessionEnvironmentImpl struct {
		*sync.Mutex
		doneChanMap              map[string]chan struct{}
		resourceID               string
		resourceSpecificTasklist string
		sessionTokenBucket       *sessionTokenBucket
	}
	sessionCreationResponse struct {
		Tasklist   string
		HostName   string
		ResourceID string
	}
)
const (
	sessionStateOpen sessionState = iota
	sessionStateFailed
	sessionStateClosed
)
const (
	sessionInfoContextKey        contextKey = "sessionInfo"
	sessionEnvironmentContextKey contextKey = "sessionEnvironment"
	sessionCreationActivityName   string = "internalSessionCreationActivity"
	sessionCompletionActivityName string = "internalSessionCompletionActivity"
	errTooManySessionsMsg string = "too many outstanding sessions"
	defaultSessionHeartbeatTimeout time.Duration = time.Second * 20
	maxSessionHeartbeatInterval    time.Duration = time.Second * 10
)
var (
	ErrSessionFailed            = errors.New("session has failed")
	errFoundExistingOpenSession = errors.New("found exisiting open session in the context")
)
func CreateSession(ctx Context, sessionOptions *SessionOptions) (Context, error) {
	options := getActivityOptions(ctx)
	baseTasklist := options.TaskListName
	if baseTasklist == "" {
		baseTasklist = options.OriginalTaskListName
	}
	return createSession(ctx, getCreationTasklist(baseTasklist), sessionOptions, true)
}
func RecreateSession(ctx Context, recreateToken []byte, sessionOptions *SessionOptions) (Context, error) {
	recreateParams, err := deserializeRecreateToken(recreateToken)
	if err != nil {
		return nil, fmt.Errorf("failed to deserilalize recreate token: %v", err)
	}
	return createSession(ctx, recreateParams.Tasklist, sessionOptions, true)
}
func CompleteSession(ctx Context) {
	sessionInfo := getSessionInfo(ctx)
	if sessionInfo == nil || sessionInfo.sessionState != sessionStateOpen {
		return
	}
	sessionInfo.sessionCancelFunc()
	completionCtx := WithActivityOptions(sessionInfo.completionCtx, ActivityOptions{
		ScheduleToStartTimeout: time.Second * 3,
		StartToCloseTimeout:    time.Second * 3,
	})
	err := ExecuteActivity(completionCtx, sessionCompletionActivityName, sessionInfo.SessionID).Get(completionCtx, nil)
	if err != nil {
		GetLogger(completionCtx).Warn("Complete session activity failed", zap.Error(err))
	}
	sessionInfo.sessionState = sessionStateClosed
	getWorkflowEnvironment(ctx).RemoveSession(sessionInfo.SessionID)
	GetLogger(ctx).Debug("Completed session", zap.String("sessionID", sessionInfo.SessionID))
}
func GetSessionInfo(ctx Context) *SessionInfo {
	info := getSessionInfo(ctx)
	if info == nil {
		GetLogger(ctx).Warn("Context contains no session information")
	}
	return info
}