Skip to content

Conversation

@GuySartorelli
Copy link
Member

@GuySartorelli GuySartorelli force-pushed the pulls/6/session-handlers branch 3 times, most recently from 69e050e to 0c113df Compare July 22, 2025 22:59
@GuySartorelli
Copy link
Member Author

Linting failure isn't related to this PR


#### `CacheSessionHandler`

If you want a more performant session save handler, you can use the [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler). This session save handler can use any cache adapter that implements `Psr\SimpleCache\CacheInterface`, though we recommend specifically using an in-memory cache adapter that gets instantiated from a factory implementing [`InMemoryCacheFactory`](api:SilverStripe\Core\Cache\InMemoryCacheFactory).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you want a more performant session save handler, you can use the [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler). This session save handler can use any cache adapter that implements `Psr\SimpleCache\CacheInterface`, though we recommend specifically using an in-memory cache adapter that gets instantiated from a factory implementing [`InMemoryCacheFactory`](api:SilverStripe\Core\Cache\InMemoryCacheFactory).
If you want a more performant session save handler, you can use the [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler). This session save handler can use any cache that implements the PSR-16 [`Psr\SimpleCache\CacheInterface`](https://www.php-fig.org/psr/psr-16/#21-cacheinterface), though we recommend specifically using an in-memory cache that gets instantiated from a factory implementing [`InMemoryCacheFactory`](api:SilverStripe\Core\Cache\InMemoryCacheFactory), such as [`MemcachedCacheFactory`](api:SilverStripe\Core\Cache\MemcachedCacheFactory) or [`RedisCacheFactory`](api:SilverStripe\Core\Cache\RedisCacheFactory).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll keep "in-memory cache adapter" because in this case it's referring specifically to adapters as documented in https://docs.silverstripe.org/en/6/developer_guides/performance/cache_adapters/#adding-an-in-memory-cache-adapter

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done but removed the bit further down which served the same purpose of pointing out redis and memcached. It was

For example, if you have Redis you can use [`RedisCacheFactory`](api:SilverStripe\Core\Cache\RedisCacheFactory), and if you have Memcached you can use [`MemcachedCacheFactory`](SilverStripe\Core\Cache\MemcachedCacheFactory).

Comment on lines 151 to 152
> [!NOTE]
> Although this is using a cache adapter, sessions won't be cleared when flushing the site.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> [!NOTE]
> Although this is using a cache adapter, sessions won't be cleared when flushing the site.
> [!NOTE]
> When using a PSR-16 compatible cache, sessions won't be cleared when flushing the site.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't matter whether they're PSR-16 or not. I'll remove the word "adapter" which is what I assume you're really after.

> [!NOTE]
> Although this is using a cache adapter, sessions won't be cleared when flushing the site.

You can define the factory which is used to instantiate the cache handler by setting the `SS_SESSION_CACHE_FACTORY` environment variable, or by setting the following YAML configuration:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can define the factory which is used to instantiate the cache handler by setting the `SS_SESSION_CACHE_FACTORY` environment variable, or by setting the following YAML configuration:
You can define the factory which is used to instantiate the cache by setting the `SS_SESSION_CACHE_FACTORY` environment variable, or by setting the following YAML configuration:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


This provides a low barrier to sharing your sessions across multiple servers, e.g. in a horizontally-scaled hosting scenario.

You can change the name of the table used by setting [`DatabaseSessionHandler.table_name`](api:SilverStripe\Control\SessionHandler\DatabaseSessionHandler->table_name) to the new table name. Note that changing the table name after sessions have already been stored in the old table will result in those sessions being invalidated, unless you manually migrate them to the new table.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can change the name of the table used by setting [`DatabaseSessionHandler.table_name`](api:SilverStripe\Control\SessionHandler\DatabaseSessionHandler->table_name) to the new table name. Note that changing the table name after sessions have already been stored in the old table will result in those sessions being invalidated, unless you manually migrate them to the new table.
You can change the name of the table used by setting [`DatabaseSessionHandler.table_name`](api:SilverStripe\Control\SessionHandler\DatabaseSessionHandler->table_name) from the default of `_sessions` to a new table name.
> [!IMPORTANT]
> Changing the table name after sessions have already been stored in the old table will result in those sessions being invalidated, unless you manually migrate them to the new table

Copy link
Member Author

@GuySartorelli GuySartorelli Jul 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't tend so say "from the default of <default value>" in docs elsewhere from what I can recall so I'll not mention _sessions explicitly. But will make the other changes.

Will use WARNING instead of IMPORTANT as per https://docs.silverstripe.org/en/6/contributing/documentation/#callout-blocks

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

| Class name | Description |
| --- | --- |
| [`FileSessionHandler`](api:SilverStripe\Control\SessionHandler\FileSessionHandler) | Stores sessions in files like the default PHP session handler, except it doesn't lock the file. This is the new default. |
| [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler) | Stores sessions in a cache adapter that implements `Psr\SimpleCache\CacheInterface`. More performance than the file session handler in most scenarios, but requires additional setup. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler) | Stores sessions in a cache adapter that implements `Psr\SimpleCache\CacheInterface`. More performance than the file session handler in most scenarios, but requires additional setup. |
| [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler) | Stores sessions in a cache that implements the PSR-16 [`Psr\SimpleCache\CacheInterface`](https://www.php-fig.org/psr/psr-16/#21-cacheinterface). More performant than the `FileSessionsHandler` in most scenarios, though requires additional setup. |

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Keeping "but" as that's my preferred word - it does the same thing as "though" in this sentence.

| --- | --- |
| [`FileSessionHandler`](api:SilverStripe\Control\SessionHandler\FileSessionHandler) | Stores sessions in files like the default PHP session handler, except it doesn't lock the file. This is the new default. |
| [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler) | Stores sessions in a cache adapter that implements `Psr\SimpleCache\CacheInterface`. More performance than the file session handler in most scenarios, but requires additional setup. |
| [`DatabaseSessionHandler`](api:SilverStripe\Control\SessionHandler\DatabaseSessionHandler) | Stores sessions in the database. Provides a low barrier to sharing your sessions across multiple servers, e.g. in a horizontally-scaled hosting scenario |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| [`DatabaseSessionHandler`](api:SilverStripe\Control\SessionHandler\DatabaseSessionHandler) | Stores sessions in the database. Provides a low barrier to sharing your sessions across multiple servers, e.g. in a horizontally-scaled hosting scenario |
| [`DatabaseSessionHandler`](api:SilverStripe\Control\SessionHandler\DatabaseSessionHandler) | Stores sessions in the database. Provides a low barrier to sharing sessions across multiple servers, e.g. in a horizontally-scaled hosting scenario |

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

| `SS_IN_MEMORY_CACHE_FACTORY` | The [`InMemoryCacheFactory`](api:SilverStripe\Core\Cache\InMemoryCacheFactory) class to use for instantiating in-memory cache adapters. See [caching adapters](/developer_guides/performance/object_caching/#adapters) for more details. |
| `SS_MANIFESTCACHE` | The manifest cache to use (defaults to file based caching). Must be a `Psr\Cache\CacheItemPoolInterface`, `Psr\SimpleCache\CacheInterface`, or `SilverStripe\Core\Cache\CacheFactory` class implementation. |
| `SS_SESSION_SAVE_HANDLER_CLASS` | Sets the classname for the session save handler to use for sessions. Alternatively set [`Session.save_handler`](api:SilverStripe\Control\Session->save_handler) via YAML configuration. See [session save handler](/developer_guides/cookies_and_sessions/sessions/#save-handler) for more details. |
| `SS_SESSION_CACHE_FACTORY` | Sets the factory to use for instantiating a cache adapter if the session save handler has been set to [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler). See [`CacheSessionHandler` docs](/developer_guides/cookies_and_sessions/sessions/#cachesessionhandler) for more details. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| `SS_SESSION_CACHE_FACTORY` | Sets the factory to use for instantiating a cache adapter if the session save handler has been set to [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler). See [`CacheSessionHandler` docs](/developer_guides/cookies_and_sessions/sessions/#cachesessionhandler) for more details. |
| `SS_SESSION_CACHE_FACTORY` | Sets the factory to use for instantiating a cache if the session save handler has been set to [`CacheSessionHandler`](api:SilverStripe\Control\SessionHandler\CacheSessionHandler). See [`CacheSessionHandler` docs](/developer_guides/cookies_and_sessions/sessions/#cachesessionhandler) for more details. |

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

You can also set it to the FQCN or injector service name of any session handler that implements [`SessionHandlerInterface`](https://www.php.net/manual/en/class.sessionhandlerinterface.php). `silverstripe/framework` comes with several non-blocking session save handlers you can use.

> [!WARNING]
> Note that in edge case scenarios, for example if your application wants to modify a session value *based on the value that is already set* and must do so for each request, non-blocking sessions may cause unexpected results.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> Note that in edge case scenarios, for example if your application wants to modify a session value *based on the value that is already set* and must do so for each request, non-blocking sessions may cause unexpected results.
> In edge case scenarios, for example if your application wants to modify a session value *based on the value that is already set* and must do so for each request, non-blocking sessions may cause unexpected results.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

factory: 'App\Session\MyCacheFactory'
```

For example, if you have Redis you can use [`RedisCacheFactory`](api:SilverStripe\Core\Cache\RedisCacheFactory), and if you have Memcached you can use [`MemcachedCacheFactory`](SilverStripe\Core\Cache\MemcachedCacheFactory).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For example, if you have Redis you can use [`RedisCacheFactory`](api:SilverStripe\Core\Cache\RedisCacheFactory), and if you have Memcached you can use [`MemcachedCacheFactory`](SilverStripe\Core\Cache\MemcachedCacheFactory).
For example, if you have Redis you can use `RedisCacheFactory`, and if you have Memcached you can use `MemcachedCacheFactory`.

API docs are linked above in my recommended changes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed as redundant to #783 (comment)

The default file-based session handler for PHP holds a lock on the session file while the session is open. This means that multiple concurrent requests from the same user have to wait for one another to finish processing after a session has been started. This includes AJAX requests.

To resolve this problem, a new [`Session.save_handler`](api:SilverStripe\Control\Session->save_handler) configuration property has been added. By default this is set to [`FileSessionHandler`](api:SilverStripe\Control\SessionHandler\FileSessionHandler) which is *non-blocking* which means that multiple concurrent requests from the same user don't have to wait for one another to finish.
To resolve this problem, we have provided three new session save handlers. Each of these are *non-blocking* which means that multiple concurrent requests from the same user don't have to wait for one another to finish.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a link / instructions for how to keep sessions blocking in the changelog in case the non-blocking sessions break something?

Copy link
Member Author

@GuySartorelli GuySartorelli Jul 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's already in the changelog

If you want to use the default blocking PHP file session handler instead, you can set the Session.save_handler configuration to null

@GuySartorelli GuySartorelli force-pushed the pulls/6/session-handlers branch from 0c113df to 44fd488 Compare July 23, 2025 03:49
@GuySartorelli GuySartorelli force-pushed the pulls/6/session-handlers branch from 44fd488 to eba7030 Compare July 23, 2025 03:51
@emteknetnz emteknetnz merged commit ece1cf1 into silverstripe:6 Jul 30, 2025
3 checks passed
@emteknetnz emteknetnz deleted the pulls/6/session-handlers branch July 30, 2025 02:59
lozcalver pushed a commit to lozcalver/developer-docs that referenced this pull request Nov 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants