gaesession

package module
v0.0.0-...-0d774a9 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2023 License: Apache-2.0 Imports: 9 Imported by: 1

README

gaesession

GoDoc

Google App Engine (GAE) support for https://github.com/icza/session.

The implementation stores sessions in the Memcache and also saves sessions in the Datastore as a backup in case data would be removed from the Memcache. This behaviour is optional, Datastore can be disabled completely. You can also choose whether saving to Datastore happens synchronously (in the same goroutine) or asynchronously (in another goroutine), resulting in faster response times.

We can use NewMemcacheStore() and NewMemcacheStoreOptions() functions to create a session Store implementation which stores sessions in GAE's Memcache. Important to note that since accessing the Memcache relies on Appengine Context which is bound to an http.Request, the returned Store can only be used for the lifetime of a request! Note that the Store will automatically "flush" sessions accessed from it when the Store is closed, so it is very important to close the Store at the end of your request; this is usually done by closing the session manager to which you passed the store (preferably with the defer statement).

So in each request handling we have to create a new session manager using a new Store, and we can use the session manager to do session-related tasks, something like this:

ctx := appengine.NewContext(r)
sessmgr := session.NewCookieManager(gaesession.NewMemcacheStore(ctx))
defer sessmgr.Close() // This will ensure changes made to the session are auto-saved
                      // in Memcache (and optionally in the Datastore).

sess := sessmgr.Get(r) // Get current session
if sess != nil {
    // Session exists, do something with it.
    ctx.Infof("Count: %v", sess.Attr("Count"))
} else {
    // No session yet, let's create one and add it:
    sess = session.NewSession()
    sess.SetAttr("Count", 1)
    sessmgr.Add(sess, w)
}

Expired sessions are not automatically removed from the Datastore. To remove expired sessions, the package provides a PurgeExpiredSessFromDSFunc() function which returns an http.HandlerFunc. It is recommended to register the returned handler function to a path which then can be defined as a cron job to be called periodically, e.g. in every 30 minutes or so (your choice). As cron handlers may run up to 10 minutes, the returned handler will stop at 8 minutes to complete safely even if there are more expired, undeleted sessions. It can be registered like this:

http.HandleFunc("/demo/purge", gaesession.PurgeExpiredSessFromDSFunc(""))

Check out the GAE session demo application which shows how it can be used. cron.yaml file of the demo shows how a cron job can be defined to purge expired sessions.

Check out the GAE session demo application which shows how to use this in action.

Documentation

Overview

Package gaesession provides Google App Engine (GAE) support for github.com/icza/session.

The implementation stores sessions in the Memcache and also saves sessions in the Datastore as a backup in case data would be removed from the Memcache. This behaviour is optional, Datastore can be disabled completely. You can also choose whether saving to Datastore happens synchronously (in the same goroutine) or asynchronously (in another goroutine), resulting in faster response times.

We can use NewMemcacheStore() and NewMemcacheStoreOptions() functions to create a session Store implementation which stores sessions in GAE's Memcache. Important to note that since accessing the Memcache relies on Appengine Context which is bound to an http.Request, the returned Store can only be used for the lifetime of a request! Note that the Store will automatically "flush" sessions accessed from it when the Store is closed, so it is very important to close the Store at the end of your request; this is usually done by closing the session manager to which you passed the store (preferably with the defer statement).

So in each request handling we have to create a new session manager using a new Store, and we can use the session manager to do session-related tasks, something like this:

ctx := appengine.NewContext(r)
sessmgr := session.NewCookieManager(gaesession.NewMemcacheStore(ctx))
defer sessmgr.Close() // This will ensure changes made to the session are auto-saved
                      // in Memcache (and optionally in the Datastore).

sess := sessmgr.Get(r) // Get current session
if sess != nil {
    // Session exists, do something with it.
    ctx.Infof("Count: %v", sess.Attr("Count"))
} else {
    // No session yet, let's create one and add it:
    sess = session.NewSession()
    sess.SetAttr("Count", 1)
    sessmgr.Add(sess, w)
}

Expired sessions are not automatically removed from the Datastore. To remove expired sessions, the package provides a PurgeExpiredSessFromDSFunc() function which returns an http.HandlerFunc. It is recommended to register the returned handler function to a path which then can be defined as a cron job to be called periodically, e.g. in every 30 minutes or so (your choice). As cron handlers may run up to 10 minutes, the returned handler will stop at 8 minutes to complete safely even if there are more expired, undeleted sessions. It can be registered like this:

http.HandleFunc("/demo/purge", gaesession.PurgeExpiredSessFromDSFunc(""))

Check out the GAE session demo application which shows how it can be used. cron.yaml file of the demo shows how a cron job can be defined to purge expired sessions.

https://github.com/icza/session/blob/master/_gae_session_demo/gae_session_demo.go

Limitations based on GAE Memcache:

- Since session IDs are used in the Memcache keys, session IDs can't be longer than 250 chars (bytes, but with Base64 charset it's the same). If you also specify a key prefix (in MemcacheStoreOptions), that also counts into it.

- The size of a Session cannot be larger than 1 MB (marshalled into a byte slice).

Note that the Store will automatically "flush" sessions accessed from it when the Store is closed, so it is very important to close the Store at the end of your request; this is usually done by closing the session manager to which you passed the store (preferably with the defer statement).

Check out the GAE session demo application which shows how to use it properly:

https://github.com/icza/gaesession/blob/master/_gae_session_demo/gae_session_demo.go

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewMemcacheStore

func NewMemcacheStore(ctx context.Context) session.Store

NewMemcacheStore returns a new, GAE Memcache session Store with default options. Default values of options are listed in the MemcacheStoreOptions type.

Important! Since accessing the Memcache relies on Appengine Context which is bound to an http.Request, the returned Store can only be used for the lifetime of a request!

func NewMemcacheStoreOptions

func NewMemcacheStoreOptions(ctx context.Context, o *MemcacheStoreOptions) session.Store

NewMemcacheStoreOptions returns a new, GAE Memcache session Store with the specified options.

Important! Since accessing the Memcache relies on Appengine Context which is bound to an http.Request, the returned Store can only be used for the lifetime of a request!

func PurgeExpiredSessFromDSFunc

func PurgeExpiredSessFromDSFunc(dsEntityName string) http.HandlerFunc

PurgeExpiredSessFromDSFunc returns a request handler function which deletes expired sessions from the Datastore. dsEntityName is the name of the entity used for saving sessions; pass an empty string to use the default value (which is "sess_").

It is recommended to register the returned handler function to a path which then can be defined as a cron job to be called periodically, e.g. in every 30 minutes or so (your choice). As cron handlers may run up to 10 minutes, the returned handler will stop at 8 minutes to complete safely even if there are more expired, undeleted sessions.

The response of the handler func is a JSON text telling if the handler was able to delete all expired sessions, or that it was finished early due to the time. Examle of a respone where all expired sessions were deleted:

{"completed":true}

Types

type MemcacheStoreOptions

type MemcacheStoreOptions struct {
	// Prefix to use when storing sessions in the Memcache, cannot contain a null byte
	// and cannot be longer than 250 chars (bytes) when concatenated with the session ID; default value is the empty string
	// The Memcache key will be this prefix and the session ID concatenated.
	KeyPrefix string

	// Number of retries to perform if Memcache operations fail due to general service error;
	// default value is 3
	Retries int

	// Codec used to marshal and unmarshal a Session to a byte slice;
	// Default value is &memcache.Gob (which uses the gob package).
	Codec *memcache.Codec

	// Tells if sessions are only to be stored in Memcache, and do not store them in Datastore as backup;
	// as Memcache has no guarantees, it may lose content from time to time, but if Datastore is
	// also used, the session will automatically be retrieved from the Datastore if not found in Memcache;
	// default value is false (which means to also save sessions in the Datastore)
	OnlyMemcache bool

	// Tells if saving in Datastore should happen asynchronously (in a new goroutine, possibly after returning),
	// if false, session saving in Datastore will happen in the same goroutine, before returning from the request.
	// Asynchronous saving gives smaller latency (and is enough most of the time as Memcache is always checked first);
	// default value is false which means to save sessions in the Datastore in the same goroutine, synchronously
	// Not used if OnlyMemcache=true.
	// FIXME: See https://github.com/icza/session/issues/3
	AsyncDatastoreSave bool

	// Name of the entity to use for saving sessions;
	// default value is "sess_"
	// Not used if OnlyMemcache=true.
	DSEntityName string
}

MemcacheStoreOptions defines options that may be passed when creating a new Memcache session store. All fields are optional; default value will be used for any field that has the zero value.

type SessEntity

type SessEntity struct {
	Expires time.Time `datastore:"exp"`
	Value   []byte    `datastore:"val"`
}

SessEntity models the session entity saved in Datastore. The Key is the session ID.

Directories

Path Synopsis
This is a session demo application that can be run on Google AppEngine platform.
This is a session demo application that can be run on Google AppEngine platform.

Jump to

Keyboard shortcuts

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