Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #12 from tedivm/content_updates

v0.12 Content Updates
  • Loading branch information...
commit d6686360912c131f46b9f8ce570b89a4c718b38f 2 parents ef207cf + 8cabfbf
@tedivm authored
View
252 API.rst
@@ -0,0 +1,252 @@
+.. _coreapi:
+
+========
+Core API
+========
+
+Pool
+====
+
+The Pool class represents the entire caching system and all of the items in it. Objects of this class are used to
+retrieve Items from the cache, as well as to perform bulk operations on the system such as Purging or Clearing the
+cache.
+
+
+setDriver
+---------
+
+*setDriver($driver)*
+
+Sets the driver for use by the caching system. This driver handles the direct interface with the caching backends,
+keeping the system specific development abstracted out.
+
+
+setLogger
+---------
+
+*setLogger($logger)*
+
+Sets a PSR LoggerInterface style logging client to enable the tracking of errors.
+
+
+setNamespace
+------------
+
+Places the Pool inside of a "namespace". All Items inside a specific namespace should be completely segmented from all
+other Items.
+
+
+getNamespace
+------------
+
+Retrieves the current namespace, or false if one isn't set.
+
+
+getItem
+-------
+
+*getItem($key)*
+
+The getItem function takes in a key and returns an associated Item object. The structure of keys can be found on the
+:ref:`basics` page.
+
+
+getItemIterator
+---------------
+
+*getItemIterator(array $keys)*
+
+The getItemIterator function takes in an array of keys and returns an Iterator object populated by Item objects for
+those keys. The structure of keys can be found on the :ref:`basics` page.
+
+
+flush
+-----
+
+*flush()*
+
+The flush function completely empties all items associated with the Pool. After calling this every Item will be considered a miss and will have to be regenerated.
+
+
+purge
+-----
+
+*purge()*
+
+The Purge function allows drivers to perform basic maintenance tasks, such as removing stale or expired items from
+storage. Not all drivers need this, as many interact with systems that handle that automatically.
+
+It's important that this function is not called from inside a normal request, as the maintenance tasks this allows can
+occasionally take some time.
+
+
+
+Item
+=====
+
+The Item class represents specific pieces of data in the caching system. Item
+objects are created by the Pool class.
+
+
+get
+----
+
+*get($invalidation == Invalidation::PRECOMPUTE, [$args])*
+
+Retrieves the stored value of the Item or null if one is not set. Because null can be a valid stored object it is
+important to call *isMiss* in order to actually check it's validity.
+
+
+The get function can take a series of optional arguments defining how it handles cache misses. The first of these
+options is the invalidation method to be used, while the other options all provide invalidation specific options. The
+:ref:`invalidation` page contains much more information about hos to use this functionality.
+
+
+isMiss
+------
+
+*isMiss()*
+
+The isMiss function returns true when the current Item has either stale or no data. Since Stash is capable of storing
+both null and false values and returning them via the get function this is the only real way to test whether a cached
+value is usable or not.
+
+The exact behavior used to define a cache miss is defined by the invalidation method used for the object. The
+:ref:`invalidation` page contains much more information about hos to use this functionality.
+
+
+lock
+----
+
+*lock($ttl = null)*
+
+This should be called right before the script attempts to regenerate data from a cache miss. It signifies to other
+processes or requests that the data is being generated and allows them to take special action to improve system
+performance. Put more simply, just call this function and your cache will be higher performing as a result.
+
+The exact effect of this function depends on which invalidation method is being used. The :ref:`invalidation` page
+contains much more information about how to use this functionality.
+
+
+set
+----
+
+*set($data, $ttl = null)*
+
+The set function is used to populate the cache with data. The first argument can be any type of data that is able to be
+serialized- essentially everything except resources and classes which can't be serialized.
+
+The second argument defines how long the Item will be stored in the cache. This is a maximum time, as Items can be
+cleared or removed earlier but will never be considered a cache hit after it. This argument can either be a DateTime
+defining a specific expiration or an integer representing the time, in seconds, that the data should be considered
+fresh.
+
+
+clear
+-----
+
+*clear()*
+
+The clear function removes the current Item's data from the backend storage.
+
+If hierarchical or "stackable" caching is being used this function will also remove children Items. The Key section of
+the :ref:`basics` document goes into more detail about how that works.
+
+
+extend
+------
+
+*extend($ttl = null)*
+
+This extends the Item's lifetime without changing it's data. Like the set function, the ttl can be a DateTime or
+integer.
+
+
+getKey
+------
+
+*getKey()*
+
+The getKey function returns this Item's key as a string. This is particularly useful when the Item is returned as a
+group of Items in an Iterator.
+
+
+getCreation
+-----------
+
+*getCreation()*
+
+This returns a DateTime of the Item's creation time, if it is available.
+
+
+getExpiration
+-------------
+
+*getExpiration()*
+
+This returns a DateTime of the Item's expiration time, if it is available.
+
+
+disable
+-------
+
+*disable()*
+
+The disable function prevents any read or write operations and forces all the other calls to fail gracefully.
+
+
+
+Drivers
+=======
+
+Stash works by storing values into various backend systems, like APC and Memcached, and retrieving them later. With the
+exception their creation and setup, drivers don't have any "public" functions- they are used by the Pool and Item
+classes themselves to interact with the underlying cache system.
+
+The :ref:`Drivers` page contains a list of all drivers and their options.
+
+setOptions
+----------
+
+*setOptions(array $options)*
+
+Passes an array of options to the Driver. This can include things like server addresses or directories to use for cache
+storage.
+
+
+DriverList
+==========
+
+The DriverList class contains functions that are useful for people integrating or extending Stash. It primarily provides
+information on what Drivers are available.
+
+getAvailableDrivers
+-------------------
+
+*DriverList::getAvailableDrivers()*
+
+Returns an associative array, $name => $class, of Drivers that can be enabled on this system.
+
+
+getAllDrivers
+-------------
+
+*DriverList::getAllDrivers()*
+
+Returns an associative array, $name => $class, of all Drivers regardless of whether they can run on this system.
+
+
+getDriverClass
+--------------
+
+*DriverList::getDriverClass($name)*
+
+Returns the class name of the requested driver.
+
+
+registerDriver
+--------------
+
+*DriverList::registerDriver($name, $class)*
+
+Adds a new Driver to the list of system drivers. This is used for extending Stash with custom drivers.
View
90 AddingDrivers.rst
@@ -0,0 +1,90 @@
+.. _addingdrivers:
+
+==============
+Adding Drivers
+==============
+
+Although Stash comes with a variety of built in Drivers there are plenty more that can be built. New Drivers are always
+appreciated, so please feel free to issue a pull request to get it included in the core library.
+
+
+Keys
+====
+
+Stash provides a variety of methods for developers to define keys, but it normalizes those keys into an array before
+passing it to the driver. For the purposes of driver development a key is always an indexed array.
+
+For example, where a user can represent a key as "path/to/data", it will always come to the Driver as
+array('path', 'to', 'data).
+
+
+DriverInterface
+===============
+
+setOptions
+---------
+
+*setOptions(array $options = array())*
+
+Sets the driver for use by the caching system. This driver handles the direct interface with the caching backends,
+keeping the system specific development abstracted out.
+
+It takes an array which is used to pass option values to the driver. As this is the only required function that is used
+specifically by the developer is is where any engine specific options should go. An engine that requires authentication
+information, as an example, should get them here.
+
+When defining this function it's important to use Key => Value pairs rather than indexed arrays, as it makes
+standardizing configuration builders easier for people integrating this library.
+
+
+getData
+-------
+*getData($key)*
+
+Returns the previously stored data as well as it's expiration date in an associative array. This array contains two
+keys- a 'data' key and an 'expiration' key. The 'data' key should be exactly the same as the value passed to storeData.
+
+In the event that data is not present simply return false.
+
+
+storeData
+---------
+*storeData(array $key, mixed $data, $expiration)*
+
+Takes in data from the exposed Stash libraries and stored it for later retrieval.
+
+* *Key* an array which should map to a specific, unique location for that array, This location should also be able to
+ handle recursive deletes, where the removal of an item represented by an identical, but truncated, key causes all of
+ the 'children' keys to be removed.
+
+* *Data* is the value meant to be stored. This is an array which contains the raw storage as well as meta data about the
+ data. The meta data can be ignored or used by the driver but entire data parameter must be retrievable exactly as it
+ was placed in.
+
+* *Expiration* is a timestamp containing representing the date and time the item will expire. This should also be
+ stored, as it is needed by the getData function.
+
+
+clear
+-----
+clear(array $key = null)
+
+Clears the cache tree using the key array provided as the key. If called with no arguments the entire cache gets cleared.
+
+
+purge
+-----
+*purge()*
+
+This function provides a space for maintenance actions in the cache. It was originally meant for removing stale items in
+storage engines that needed manual actions to do so (sqlite, filesystem) but can be used for any maintenance that should
+not occur during regular user operations.
+
+
+isAvailable
+-----------
+*isAvailable()*
+
+Returns whether the driver is able to run in the current environment or not. Any system checks - such as making sure any
+required extensions are missing - should be done here. This is a general check; if any instance of this driver can be
+used in the current environment it should return true.
View
251 Basics.rst
@@ -1,5 +1,252 @@
-.. _examples:
+.. _basics:
===========
Basic Usage
-===========
+===========
+
+Concepts
+========
+
+Pools and Items
+---------------
+
+The Pool class represents the caching system as a whole, while the Item class represents the pieces of data that are
+stored in it. Item classes get pulled out of the Pool when they are needed (in other words, Pools are Item Factories).
+
+
+Drivers
+-------
+
+Drivers allow Stash to interact with different caching systems by abstracting away the system specific APIs.
+
+For the most part Drivers are invisible. Once they're created and injected into the Pool they can be forgotten about.
+If you're using Stash with a framework, such as the Symfony Stash Bundle, you can ignore drivers altogether.
+
+
+Keys
+----
+
+Keys are unique strings that map to data in the caching system. Each Item is associated with a Key. At the simplest
+level Keys can be looked at as alphanumeric strings with a one to one mapping. This works like most traditional caching
+systems, with each key mapping to a single piece of data in the caching system.
+
+Stash also has a special kind of grouping system that allow cache items to be nested by adding a slash to Keys (the same
+syntax as identifying folders on a filesystem). These slashes tells Stash where the nesting points are. Nesting allows
+developers to organize items just like they would files and folders on a computer. This makes clearing groups of items
+in the cache as simple as clearing their parent node, just like deleting a directory would erase all the files underneath.
+
+A project that had different models, each identified by an id and a type, might have it's keys for those models start
+with models/type/id, with individual pieces of data stored in keys inside of those. If the user "bob" had the id "32",
+the path to his data in the cache would be "models/users/32".
+
+
+Namespaces
+----------
+
+Namespaces provide a simple way of grouping cache data together and isolating it from other data in the system.
+Namespaces are set on the Pool, with each subsequent Item retrieved from the Pool being a member of that Namespace. Two
+Items with the same key but different Namespaces will refer to different data, and actions performed on a Pool with a
+set Namespace only affects that Namespace.
+
+
+Examples
+========
+
+
+Creating Items
+--------------
+
+Creating an Item with Stash is simple-
+
+.. code-block:: php
+
+ <?php
+ $pool = new Stash\Pool();
+
+ // Set the "key", which is the path the Stash object points to.
+ $item = $pool->getItem('path/to/data');
+
+This will create a Pool using the default "Ephemeral" driver. Data will be cached for the lifetime of the request, but
+will not be available to future requests. In order to cache data across requests a drivers is needed.
+
+.. code-block:: php
+
+ <?php
+ // Create Driver with default options
+ $driver = new Stash\Driver\FileSystem();
+ $driver->setOptions(array());
+
+ // Inject the driver into a new Pool object.
+ $pool = new Stash\Pool($driver);
+
+ // New Items will get and store their data using the same Driver.
+ $item = $pool->getItem('path/to/data');
+
+Each driver object can be used by many different Pool objects, and each of those Pools will then have access to the
+same data.
+
+Items can be retrieved from the Pool class individually or in groups.
+
+.. code-block:: php
+
+ <?php
+ // Create Driver with default options
+ $driver = new Stash\Driver\FileSystem();
+
+ // Create pool and inject driver
+ $pool = new Stash\Pool($driver);
+
+ // Retrieve a single cache item
+ $item = $pool->getItem('path/to/data');
+
+ // Retrieve an iterator containing multiple cache items
+ $items = $pool->getItemIterator('path/to/data', 'path/to/more/data');
+
+
+Identifying Items
+-----------------
+
+The examples so far show how to get Items using a Key represented as a string. It is also possible to represent a Key
+as an array or a series of function arguments. Each of these methods will retrieve the same Item, this is just some
+syntactic sugar developers can use.
+
+.. code-block:: php
+
+ <?php
+ // Pass the key as a string
+ $item = $pool->getItem('models/users/' . $id . '/info');
+
+ // Pass the key as an array
+ $item = $pool->getItem(array('models', 'users', $id, 'info'));
+
+ // Pass the key as a series of arguments
+ $item = $pool->getItem('models', 'users', $id, 'info');
+
+
+Caching Data
+------------
+
+Storing and Retrieving Data is done through the Item class. Four functions do the bulk of the work:
+
+* *get()* - Returns data that was previously stored, or null if nothing stored. (Since it is possible to store null
+ values it is very important not to rely on a null return to check for a cache miss.)
+
+* *isMiss()* - Returns true if no data is stored or the data is stale; returns false if fresh data is present.
+
+* *lock()* - This is used to let other processes know that this process is generating new data.
+
+* *set($data, $ttl = null)* - Stores the specified data for use by other requests.
+
+Using these four functions, you can create simple cache blocks -- pieces of code where you fetch data, check to see if
+it's fresh, and then regenerate and store the data if it was stale or absent.
+
+.. code-block:: php
+
+ <?php
+
+ // Get a cache item.
+ $item = $pool->getItem('path/to/item');
+
+ // Attempt to get the data
+ $data = $item->get();
+
+ // Check to see if the data was a miss.
+ if($item->isMiss())
+ {
+ // Let other processes know that this one is rebuilding the data.
+ $item->lock();
+
+ // Run intensive code
+ $data = codeThatTakesALongTime();
+
+ // Store the expensive to generate data.
+ $item->set($data);
+ }
+
+ // Continue as normal.
+ useDataForStuff($data);
+
+
+The *set* function can take an optional "expiration" argument, which allows developers to set either a TTL in seconds
+or an explicit expiration using a DateTime object.
+
+.. code-block:: php
+
+ <?php
+
+ // Get cache item.
+ $item = $pool->getItem('path/to/item');
+
+ // Using an age.
+ $data = $pool->get();
+ if($item->isMiss())
+ {
+ $data = expensiveFunction();
+ // Cache expires in one hour.
+ $item->set($data, 3600);
+ }
+
+
+ // Using a DateTime.
+ $data = $item->get();
+ if($item->isMiss())
+ {
+ $data = expensiveFunction();
+
+ // Cache expires January 21, 2015.
+ $expiration = new DateTime('2015-01-21');
+ $item->set($data, $expiration);
+ }
+
+
+.. NOTE::
+ The expiration time only sets a maximum time the Item can be considered fresh, not a minimum. Items can be
+ invalidated from the cache before their expiration time for a number of reasons. Stash will also attempt to
+ distribute cache misses to normalize system load. At no point will an Item be considered fresh after the expiration
+ or ttl is reached.
+
+
+Clearing Data
+-------------
+
+Clearing data is just as simple as getting it. Note that clearing a key will clear that key *and any keys beneath it in
+the hierarchy.*
+
+.. code-block:: php
+
+ <?php
+ // Clearing a key.
+ $item = $pool->getItem('path/to/data/specific/123')
+ $item->clear();
+
+ // Clearing a key with subkeys
+ $item = $pool->getItem('path/to/data')
+ $item->clear(); // clears 'path/to/data/*' as well as 'path/to/data'
+
+
+Emptying the Entire Cache
+-------------------------
+
+The Pool class can also empty the entire cache:
+
+.. code-block:: php
+
+ <?php
+ $pool->flush();
+
+
+Running Maintenance
+-------------------
+
+Some caching systems require maintenance actions to occur. This can include things such as removing stale data or
+reindexing for improved performance.
+
+.. code-block:: php
+
+ <?php
+ $pool->purge();
+
+.. NOTE::
+ Depending on the size of the cache and the specific drivers in use this can take some time, so it is best called as
+ part of a separate maintenance task or as part of a cron job.
+
View
180 Classes.rst
@@ -1,180 +0,0 @@
-.. _coreclasses:
-
-============
-Core Classes
-============
-
-Drivers
-=======
-
-Stash works by storing values into various backend systems, like APC and
-Memcached, and retrieving them later. With the exception of the constructors,
-drivers don't have any "public" functions- they are used by the Pool and Item
-classes themselves to interact with the underlying cache system.
-
-The :ref:`Drivers` page contains a list of all drivers and their options.
-
-
-Pool
-====
-
-The Pool class represents the entire caching system and all of the items in it.
-Objects of this class are used to retrieve Items from the cache, as well as to
-perform bulk operations on the system such as Purging or Clearing the cache.
-
-
-Constructor
------------
-
-*construct($driver)*
-
-The Pool constructor takes in a driver as an argument.
-
-
-getItem
--------
-
-*getItem($key)*
-
-The getItem function takes in a key and returns an associated Item object. The
-structure of keys can be found on the :ref:`basics` page.
-
-
-getItemIterator
----------------
-
-*getItemIterator(array $keys)*
-
-The getItemIterator function takes in an array of keys and returns an Iterator
-object populated by Item objects for those keys. The structure of keys can be
-found on the :ref:`basics` page.
-
-
-flush
------
-
-*flush()*
-
-The flush function completely empties all items associated with the Pool. After
-calling this every Item will be considered a miss and will have to be
-regenerated.
-
-
-purge
------
-
-*purge()*
-
-The Purge function allows drivers to perform basic maintenance tasks, such as
-removing stale or expired items from storage. Not all drivers need this, as many
-interact with systems that handle that automatically.
-
-It's important that this function is not called from inside a normal request, as
-the maintenance tasks this allows can occasionally take some time.
-
-
-Item
-=====
-
-The Item class represents specific pieces of data in the caching system. Item
-objects are created by the Pool class.
-
-
-get
----
-
-*get($invalidation, [$args])*
-
-The get function the data mapped to this particular Item. If no value is stored
-at all then this function will return null. Since this can return false or null
-as a correctly cached value, the return value should not be used to determine
-successful retrieval of data- for that use the "isMiss()" function after calling
-this one.
-
-The get function can take a series of optional arguments defining how it handles
-cache misses. The first of these options is the invalidation method to be used,
-while the other options all provide invalidation specific options. The
-:ref:`invalidation` page contains much more information about hos to use this
-functionality.
-
-
-isMiss
-------
-
-*isMiss()*
-
-The isMiss function returns true when the current Item has either no data or
-stale data. Since Stash is capable of storing both null and false values and
-returning them via the get function, this is the only real way to test whether
-a cached value is usable or not.
-
-The exact behavior used to define a cache miss is defined by the invalidation
-method used for the object. The :ref:`invalidation` page contains much more
-information about hos to use this functionality.
-
-
-set
----
-
-*set($data, $ttl = null)*
-
-The set function is used to populate the cache with data. The first argument
-can be any type of data that is able to be serialized- essentially everything
-except resources and classes which can't be serialized. All data put into Stash
-will either come back exactly as inserted or not at all.
-
-The second argument defines how long the item will be stored in the cache. This
-is a maximum time, as items can be cleared or removed earlier depending on a
-number of factors. This argument can be an integer representing the time, in
-seconds, that the item will be considered valid. It can also be passed a
-DateTime object signifying the exact moment the data should expire. Finally, for
-items that are regenerated some other way, or which will never change, a null
-value can be passed.
-
-
-clear
------
-
-*clear()*
-
-The clear function removes the current Item's data from the backend storage.
-
-If hierarchical or "stackable" caching is being used this function will also
-remove children Items. The Key section of the :ref:`basics` document goes into
-more detail about how that works.
-
-
-lock
-----
-
-*lock($ttl = null)*
-
-The lock function is used to tell other processes and requests that this
-particular item is being regenerated. This is typically called after the
-"isMiss" function returns true, before the Item is regenerated and stored using
-"set". Depending on the Invalidation method set for this Item, this prevents
-multiple requests from attempting to regenerate the data in question,
-potentially preventing a cache stampede (also known as the dogpile effect) as
-multiple scripts attempt to run the same expensive code.
-
-The exact effect of this function depends on which invalidation method is being
-used. The :ref:`invalidation` page contains much more information about hos to
-use this functionality.
-
-
-disable
--------
-
-*disable()*
-
-The disable function disables all access to the "Driver" and forces the Item
-class to gracefully fail most of it's calls.
-
-
-getKey
-------
-
-*getKey()*
-
-The getKey function returns this Item's key as a string. This is particularly
-useful when the Item is returned as a group of Items in an Iterator.
View
5 Contents.rst
@@ -9,9 +9,10 @@ Stash Documentation
Basics
Grouping
Invalidation
- Examples
- Classes
+ API
Drivers
Integration
Extending
+ AddingDrivers
Contributing
+ FAQ
View
69 Contributing.rst
@@ -4,3 +4,72 @@
Contributing
============
+Contributions Welcome!
+======================
+
+Pull Requests and Community Contributions are the bread and butter of open source software. Every contribution- from bug
+reports to feature requests, typos to full new features- are greatly appreciated.
+
+Important Guidelines
+====================
+
+- One Item Per Pull Request or Issue. This makes it much easier to review code and merge it back in, and prevents
+ issues with one request from blocking another.
+
+- Code Coverage is extremely important, and pull requests are much more likely to be accepted if testing is also
+ improved. New code should be properly tested, and all tests must pass.
+
+- Read the LICENSE document and make sure you understand it, because your code is going to be released under it.
+
+- Be prepared to make revisions. Don't be discouraged if you're asked to make changes, as that is just another step towards refining the code and getting it merged back in.
+
+- Remember to add the relevant documentation, particular the docblock comments.
+
+Code Styling
+============
+
+This project follows the PSR standards set forth by the `PHP Framework
+Interop Group <http://www.php-fig.org/>`__.
+
+- `PSR-0: Class and file naming conventions <https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md>`__
+- `PSR-1: Basic coding standard <https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md>`__
+- `PSR-2: Coding style guide <https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md>`__
+
+All code most follow these standards to be accepted. The easiest way to accomplish this is to run php-cs-fixer once the
+new changes are finished. The php-cs-fixer package is installed as a development dependency of this project.
+
+.. code-block:: bash
+
+ composer install --dev
+ vendor/bin/php-cs-fixer fix ./ --level="all" -vv
+
+Running the test suite
+======================
+
+First install dependencies using Composer. It's important to include the dev packages:
+
+.. code-block:: bash
+
+ composer install --dev
+
+The "runTests.sh" script runs the full test suite- phpunit,
+php-cs-fixer, as well as any environmental setup:
+
+.. code-block:: bash
+
+ tests/runTests.sh
+
+To call phpunit directly:
+
+.. code-block:: bash
+
+ vendor/bin/phpunit
+
+To call php-cs-fixer directly:
+
+.. code-block:: bash
+
+ vendor/bin/php-cs-fixer fix ./ --level="all" -vv --dry-run
+
+
+
View
56 Drivers.rst
@@ -4,8 +4,11 @@
Drivers
=======
+System
+======
+
FileSystem
-==========
+----------
The Filesystem driver stores each item in a php script, as native php.
Unsurprisingly this is the fastest backend for small to medium sites, as it is
@@ -39,11 +42,11 @@ compared to the other drivers.
// Setting a custom path is done by passing an options array to the constructor.
$options = array('path' => '/tmp/myCache/');
- $driver = new Stash\Driver\FileSystem($options);
+ $driver->setOptions($options);
Sqlite
-======
+------
An alternative file based caching backend is the Sqlite driver. It can use
either the PDO or native sqlite extensions, and can use either sqlite2 or
@@ -87,11 +90,11 @@ sqlite3.
// Setting a custom path is done by passing an options array to the constructor.
$options = array('path' => '/tmp/myCache/');
- $driver = new Stash\Driver\Sqlite($options);
+ $driver->setOptions($options);
APC
-===
+---
The APC extension is one of the most well known php caching extensions, allowing
for both php opcode caching and memory storage of php values. The StashApc
@@ -117,21 +120,14 @@ to use.
// Setting a custom path is done by passing an options array to the constructor.
$options = array('ttl' => 3600, 'namespace' = md5(__file__));
- $driver = new Stash\Driver\Apc($options);
-
-
-
-Xcache (experimental)
-=====================
-
-The Xcache driver is currently experimental.
+ $driver->setOptions($options);
-Like the APC driver, the Xcache driver stores data directly in memory for use by
-other scripts.
+Server
+======
Memcached
-=========
+---------
Memcached is a client/server application which allows machines to pool their
memory together as one large memory cache. The Memcached driver is a feature
@@ -158,18 +154,24 @@ complete driver for Memcached, complete with hierarchical caching.
<?php
// One Server
- $driver = new Stash\Driver\Memcache(array('servers' => array('127.0.0.1', '11211')));
+ $driver = new Stash\Driver\Memcache();
+ $driver->setOptions(array('servers' => array('127.0.0.1', '11211')));
// Multiple Servers
+ $driver = new Stash\Driver\Memcache();
+
$servers = array();
$servers[] = array('127.0.0.1', '11211', 60);
$servers[] = array('10.10.10.19', '11211', 20);
$servers[] = array('10.10.10.19', '11211', 20);
- $driver = new Stash\Driver\Memcache(array('servers' => $servers));
+ $driver->setOptions(array('servers' => $servers));
+
// Using memcached options
+ $driver = new Stash\Driver\Memcache();
+
$options = array();
$options['servers'][] = array('mem1.example.net', '11211');
$options['servers'][] = array('mem2.example.net', '11211');
@@ -179,11 +181,11 @@ complete driver for Memcached, complete with hierarchical caching.
$options['cache_lookups'] = true;
$options['serializer'] = 'json';
- $driver = new Stash\Driver\Memcache($options);
+ $driver->setOptions($options);
Redis
-=====
+-----
Redis is a high performing advanced caching and key/value storage system. This
driver uses the Redis PHP extension to enable Redis based caching, using one or
@@ -198,21 +200,27 @@ more servers.
<?php
// One Server
- $driver = new Stash\Driver\Redis(array('servers' => array('127.0.0.1', '6379')));
+ $driver = new Stash\Driver\Redis();
+ $driver->setOptions(array('servers' => array('127.0.0.1', '6379')));
// Multiple Servers
+ $driver = new Stash\Driver\Redis();
+
$servers = array();
$servers[] = array('127.0.0.1');
$servers[] = array('10.10.10.20');
$servers[] = array('10.10.10.19', '6379');
$servers[] = array('10.10.10.19', '6380');
- $driver = new Stash\Driver\Redis(array('servers' => $servers));
+ $driver->setOptions(array('servers' => $servers));
+
+Specialized
+===========
Ephemeral
-=========
+---------
The Ephemeral driver is a special backend that only stores data for the lifetime
of the script, whether it be a longer running process or a web request. Items
@@ -244,7 +252,7 @@ On subsequent requests, however, the data is not there-
Composite
-=========
+---------
The Composite driver acts as a wrapper around one or more drivers, allowing
different drivers to work together in a single cache.
View
214 Examples.rst
@@ -1,214 +0,0 @@
-.. _examples:
-
-========
-Examples
-========
-
-
-Creating Stash Objects
-======================
-
-Creating a basic Stash object is simple:
-
-.. code-block:: php
-
- <?php
- $stash = new Stash\Pool();
-
- // Set the "key", which is the path the Stash object points to.
- $item = $stash->getItem('path/to/data');
-
-This will create a cache object with no cross request storage, meaning the data
-will only be cached for the lifetime of that one script or request. In order to
-store cache results across requests, we need a driver. Each driver interfaces
-with a specific form of persistent storage.
-
-
-.. code-block:: php
-
- <?php
- // Create Driver with default options
- $stashFileSystem = new Stash\Driver\FileSystem();
-
- // Create the actual cache object, injecting the backend
- $stash = new Stash\Pool($stashFileSystem);
-
- // Set the "key", which is the path the Stash object points to. This will be
- // discussed in depth later, but for now just know it's an identifier.
- $item = $stash->getItem('path/to/data');
-
-Each driver object can be used by many different cache objects, so that any
-initial setup and overhead (database connections, file drivers, etc.) can be
-done only once per request. In order to simplify this process, the Pool class
-automates the process of driver creation to ensure that all cache objects use
-the same drivers.
-
-.. code-block:: php
-
- <?php
- // Create Driver with default options
- $stashFileSystem = new Stash\Driver\FileSystem();
-
- // Create pool and inject driver
- $pool = new Stash\Pool($stashFileSystem);
-
- // Retrieve a single cache item
- $item = $pool->getItem('path/to/data');
-
- // Retrieve an iterator containing multiple cache items
- $items = $pool->getItemIterator('path/to/data', 'path/to/more/data');
-
-
-Identifying Items Using Keys
-==================================
-
-Stash identifies items in the cache pool using keys, which are just simple
-strings. Stash has a special kind of grouping system that allow cache items to
-be nested, similar to how folders are nested in filesystems, by adding a slash
-to Keys. The slash tells the Implementing Library where the nesting points are.
-If no nesting is used, Stacks behave exactly like the standard Cache interfaces.
-Nesting allows developers to organize items just like they would files and
-folders on a computer. This makes clearing groups of items in the cache as
-simple as clearing their parent node, just like deleting a directory would erase
-all the files underneath.
-
-A project that had different models, each identified by an id and a type, might
-have it's keys for those models start with models/type/id, with individual
-pieces of data stored in keys inside of those. If the user "bob" had the id
-"32", the path to his data in the cache would be "models/users/32".
-
-Stash accepts keys in two forms: as a slash-delimited string, or as a series of
-arguments representing each level of nesting. Both work in exactly the same way.
-
-.. code-block:: php
-
- <?php
- // Pass the key as a string
- $stashItem = $pool->getItem('models/users/' . $id . '/info');
-
- // Pass the key as a series of arguments
- $stashItem = $pool->getItem('models', 'users', $id, 'info');
-
-Storing and Retrieving Data
-===========================
-
-Storing data in Stash (and retrieving it in future requests) is easy. Three
-functions do the bulk of the work:
-
-* *get()* - Returns data that was previously stored, or null if nothing stored.
- (Since it is possible to store null values it is very important not to rely on a
- null return to check for a cache miss.)
-
-* *isMiss()* - Returns true if no data is stored or the data is stale; returns
- false if fresh data is present.
-
-* *set($data, $ttl = null)* - Stores the specified data in the driver's
- persistent storage.
-
-Using these three functions, you can create simple cache blocks -- pieces of
-code where you fetch data, check to see if it's fresh, and then regenerate and
-store the data if it was stale or absent.
-
-.. code-block:: php
-
- <?php
-
- // Get cache item.
- $stashItem = $pool->getItem('path/to/item');
-
- // Attempt to "get"
- $data = $stashItem->get();
-
- // Check to see if the data was a miss.
- if($stashItem->isMiss())
- {
- // Run intensive code
- $data = codeThatTakesALongTime();
-
- // Store data.
- $stashItem->set($data);
- }
-
- // Continue as normal.
- return $data;
-
-The *set* function can take the expiration as an additional argument. This
-expiration can be a time, in seconds, that the cache should live or it can be a
-DateTime object that represents the time the cached item should expire. (This
-argument can be negative, which will result in an immediately stale cache.)
-
-.. code-block:: php
-
- <?php
-
- // Get cache item.
- $stashItem = $pool->getItem('path/to/item');
-
- // Using an age.
- $data = $stash->get();
- if($stashItem->isMiss())
- {
- $data = expensiveFunction();
- // Cache expires in one hour.
- $stashItem->set($data, 3600);
- }
-
-
- // Using a DateTime.
- $data = $stashItem->get();
- if($stashItem->isMiss())
- {
- $data = expensiveFunction();
-
- // Cache expires January 21, 2012.
- $expiration = new DateTime('2012-01-21');
- $stashItem->set($data, $expiration);
- }
-
-The expiration sets the *maximum* time a cached object can remain fresh. In
-order to distribute cache misses, the Stash system tries to vary the expiration
-time for items by shortening a random amount; some drivers may also have size
-restrictions or other criteria for removing items early, and items can be
-cleared manually before they expire. Items will never be reported as fresh
-*after* the expiration time passes, however.
-
-
-Clearing Data
-=============
-
-Clearing data is just as simple as getting it. As with the *get* and *store*
-functions, the *clear* function takes a set key - if one isn't set then the
-entire cache is cleared. Note that clearing a key will clear that key *and any
-keys beneath it in the hierarchy.*
-
-.. code-block:: php
-
- <?php
- // Clearing a key.
- $stashItem = $pool->getItem('path/to/data/specific/123')
- $stashItem->clear();
-
- // Clearing a key with subkeys
- $stashItem = $pool->getItem('path/to/data/general') // clears 'path/to/data/*'
- $stashItem->clear();
-
-The Pool class can also empty the entire cache:
-
-.. code-block:: php
-
- <?php
- $pool->flush();
-
-
-Purging Data
-============
-
-The *purge* function removes stale data from the cache backends while leaving
-current data intact. Depending on the size of the cache and the specific drivers
-in use this can take some time, so it is best called as part of a separate
-maintenance task or as part of a cron job.
-
-.. code-block:: php
-
- <?php
- $pool->purge();
View
54 Extending.rst
@@ -4,3 +4,57 @@
Extending
=========
+Getting Started
+===============
+
+The process of extending Stash is pretty straight forward-
+
+* Create the new class, either extending the existing one or implementing the Interface.
+* Extend the AbstractTest and configure it to use the newly created class.
+* Run the test suite and fix any bugs that appear.
+* Add additional tests for any custom behavior that was added.
+
+
+Interfaces
+==========
+
+In the Integration section it's recommended that developers typehint against the built in interfaces, and this allows
+any code written that impliments get used by all of those developers. It also makes it clear to developers extending
+Stash which changes are breaking expectations of users of the library. The interfaces are extensively commented, and
+reading them directly is by far the best way to understand what is expected of the things that implement them.
+
+When extending the Pool and Item classes it's highly recommended that the built in classes be utilized
+and built off of, but any class that passes the test suite and impliments the relevant interfaces should be able to be
+swapped in for the equivalent Stash class without problem. When building Drivers it is often easier to start with a
+fresh slate and simply build out the DriverInterface.
+
+Relevant Interfaces:
+
+* *Stash\\Interfaces\\PoolInterface*
+* *Stash\\Interfaces\\ItemInterface*
+* *Stash\\Interfaces\\DriverInterface*
+
+
+AbstractTests
+=============
+
+While Interfaces define an API contract, Tests make sure they're enforced. To make development easier there is an
+AbstractTest for every Interface with a full suite of tests to ensure proper behavior. Using each suite is done by
+creating the new test class and extending it off of the AbstractTest (rather than the typical
+PHPUnit_Framework_TestCase), and then setting the appropriate class attribute to let the new test know which class they
+should be testing.
+
+* *Stash\\Tests\\AbstractPoolTest*- Set 'poolClass'.
+* *Stash\\Tests\\AbstractItemTest*- Set 'itemClass'.
+* *Stash\\Tests\\Driver\\AbstractDriverTest*- Set 'driverClass'.
+
+
+Replacing The Item Class
+========================
+
+When extending the Pool it's easy to also change the Item class by overriding the "itemClass" protected variable with
+the new Item class name.
+
+To change the Item class without having to make a new Pool class as well the Pool->setItemClass() method can be used. It
+has to be called for each new Pool instance, and the new Item class must implement the ItemInterface or an exception
+will be thrown.
View
58 FAQ.rst
@@ -0,0 +1,58 @@
+.. _faq:
+
+====
+FAQ
+====
+
+Packaging
+=========
+
+* **When is version 1.0 coming out?**
+
+Right now the biggest thing holding back v1.0 is the completion of the PSR-Caching proposal. This proposal is meant to
+define a common caching interface that libraries such as Stash can expose to any library that desires caching. Once this
+is complete and we can be sure that Stash does not have anything in it that would prevent it from adopting this standard
+a v1.0 release will be made and the Stash API will be stabilized.
+
+
+* **What happened to the PEAR repositories?**
+
+Frankly, the PEAR repositories were not getting nearly enough traffic to justify the work it took in maintaining them.
+With modern packaging systems like Composer it's time to move on from PEAR.
+
+
+
+Compatibility
+=============
+
+* **What's all this PSR stuff I keep heading about?**
+
+PSR's are documents published by the PHP Framework Interoperability Group, of which Stash is a member. This group
+attempts to make code more easily shared between libraries, frameworks and applications by creating standards that can
+be used to ensure interoperability. Following these standards makes Stash more portable, and Stash can take advantage
+of other libraries, such as monolog, that expose functionality through their own PSRs.
+
+
+* **Does Stash work on Windows and OSX?**
+
+Yup! Some drivers may have special options that need to be set, but these are all documented.
+
+
+Drivers
+=======
+
+* **Why don't you support xcache?**
+
+Unfortunately xcache does not allow itself to be loaded when being run from the command line. Although this makes sense
+in theory, as cli scripts are not going to share memory between runs, it makes testing extremely difficult and without
+testing it's hard to make high quality drivers.
+
+
+* **Why don't you support wincache?**
+
+Because we don't have a windows box to test it on, although that may change.
+
+
+* **Can you support X caching system?**
+
+We're happy to take requests, but even happier when they're pull requests.
View
34 Grouping.rst
@@ -2,4 +2,36 @@
=========
Groupings
-=========
+=========
+
+Grouping is an extremely important feature of caching. By making it easier for developers to clear out related items
+and for framework and application developers to isolate data among components, caching will become more common place and
+application performance will improve as a result.
+
+Stash offers two methods of grouping, Stacks and Namespaces. Although similar they are meant to serve distinct purposes-
+Stacks are meant to give developers the ability to organize and invalidate their data in logical groups, while
+Namespaces exist to let frameworks isolate different systems from each other. Combined they allow library and
+application developers the ability to create Stacks and use Keys without having to worry key collision or what other
+libraries may be storing in the cache.
+
+Stacks
+======
+
+Stacks are a special kind of grouping system that allow cache items to be nested, similar to how folders are nested in
+filesystems. Stacks work by adding a special character to Keys, the slash, which tells the Implementing Library where
+the nesting points are. If the first character of the key is not a slash, Stacks behaves exactly like the standard Cache
+interfaces.
+
+An example key may look like "/Users/Bob/Friends", "/Users/Bob/Friends/Active" or just "/Users/Bob". The special thing
+about Stacks is that clearing out "/Users/Bob" also clears out "/Users/Bob/Friends" and "/Users/Bob/Friends/Active".
+
+
+Namespaces
+==========
+
+Namespaces can be used to separate the storage of different systems in the cache. This allows different sections to be
+cleared on an individual level, while also preventing overlapping keys.
+
+Namespaces are controlled by the Pool::setNamespace($name) function. Once a namespace is set all operations the Pool and
+it's subsequent children Items do will in that isolated namespace (Items pulled out of the Pool before a namespace
+change maintain their original namespace).
View
98 Integration.rst
@@ -4,42 +4,86 @@
Integration
===========
+Integrating Stash into a project consists of three components- Initializing the Drivers and Pool, making the subsequent
+Pool available for consumption, and actually utilizing Stash to cache data.
-Installation
-------------
+The easiest way to integrate Stash is to use an existing framework that takes care of the Initialize and Availability
+portions of integration- the TedivmStashBundle for Symfony is one example of this. This is by no means a requirement
+though, and integrating Stash can be a rather straight forward process.
-Stash is available as a direct download through `GitHub
-<https://github.com/tedivm/Stash/releases>`_, through Pear via the `
-pear.tedivm.com <http://pear.tedivm.com>`_ channel, or the preferred method of
-using `Composer <http://getcomposer.org/>`_.
+This page has general pointers that everyone should consider when working with Stash.
-When using Composer it's important to remember that Stash follows semantic
-versioning, but has still not reached it's 1.0.0 release. This means care should
-be given when updating MINOR versions, but that PATCH versions will always be
-backwards compatible. The recommended Composer requirement should look like-
- "tedivm/stash": "0.11.*"
+Typehinting
+===========
+
+There will be times when Stash objects need to be passed around. A class may have a setCache($pool) function, for
+example, and as a developer it makes sense to typehint for a Pool object. In instances like this it is important to
+typehint against the supplied Interfaces themselves, rather than the specific classes, in order to facilitate
+interoperability with code that extends Stash.
+
+Interfaces are all in the Stash\\Interfaces namespace and consist of-
+
+* Stash\\Interfaces\\PoolInterface
+* Stash\\Interfaces\\ItemInterface
+* Stash\\Interfaces\\DriverInterface
+
+
+DriverList
+==========
+
+The Stash\\DriverList class contains static functions that ease integration.
+
+* *getAllDrivers()* - Returns an array of drivers and their respective classes.
+* *getAvailableDrivers()* - Returns the above list, filtered by drivers that can run on the current system.
+* *getDriverClass($name)* - Takes the shortname of a Driver and returns it's class name.
+* *registerDriver($name, $classname)* - Registers new Drivers with the class.
+
+Configuration
+=============
-Where 0.11 can be replaced with the version you've developed against.
+All Drivers have a "setOptions" function that takes in options as Key => Value pairs in an array. This makes converting
+saved configurations (such as from an XML, YAML, or INI file) a fairly straight forward process of taking that "options"
+sections and converting it to an array. Complete configuration options for each Driver are available for use on any
+additional validation that developers may want to provide.
+
+
+Driver Wrapping
+===============
+
+There is almost never a reason not to use the Composite Driver to put the Ephemeral Driver in front of the primary
+caching Driver. It reduces load on the caching system and increases performance by reducing duplicate requests. It also
+helps normalize development as everything can be left the same except that the persistent drivers are left off.
Logging
--------
+=======
+
+Stash supports logging through third party logging libraries such as monolog. It does this by following PSR-3, with the
+Pool class utilizing the `PSR-3 LoggerAwareInterface <http://www.php-fig.org/psr/3/>`_. PSR-3 compliant logging libraries
+can be injected into the Pool class through the setLogger method.
+
+Logging is a powerful feature to give system admins, as it gives them access to errors that occur in with the logging
+system. Stash suppresses many types of errors to allow processes to continue as normal, making logging an important part
+of integration.
-Stash supports logging through third party logging libraries, such as monolog.
-It does this by following the `PSR-3
-LoggerAwareInterface <http://www.php-fig.org/psr/3/>`_. Caching events of all
-varieties- from simple hit or miss numbers to driver errors and other exceptions-
-can be exposed to analysis by injecting a compliant logging object into any Pool
-instance.
+
+Maintenance Actions
+===================
+
+Some drivers require that maintenance action be performed regular. The FileSystem and SQLite drivers, as an example,
+need to remove old data as they can't do it automatically. These operations are all abstracted away behind Pool->purge()
+but will need to be called regularly by the integrating applications.
+
+The Pool->purge() function should be called as a stand alone operation. Depending on the Driver being used this can take
+longer than your typical action and should not be tied to a user request. It is also recommended that this be run from a
+command line where possible, such as in an automated cron job, in order to improve performance.
Standards Compliance
---------------------
-
-Stash complies with `PSR-0 <http://www.php-fig.org/psr/0/>`_.,
-`PSR-1 <http://www.php-fig.org/psr/1/>`_., `PSR-2
-<http://www.php-fig.org/psr/2/>`_. and `PSR-3 <http://www.php-fig.org/psr/3/>`_.
-This makes integration with other projects easier, as it shares a common defined
-code standard, follows naming scemes which allow for shared autoloaders, and
-opens itself up to integration with other libraries.
+====================
+
+Stash complies with `PSR-0 <http://www.php-fig.org/psr/0/>`_., `PSR-1 <http://www.php-fig.org/psr/1/>`_., `PSR-2
+<http://www.php-fig.org/psr/2/>`_. and `PSR-3 <http://www.php-fig.org/psr/3/>`_. This makes integration with other
+projects easier, as it shares a common defined code standard, follows naming scemes which allow for shared autoloaders,
+and opens itself up to integration with other libraries.
View
136 Invalidation.rst
@@ -4,32 +4,57 @@
Invalidation
============
+Dog Pile Effect
+===============
+
+The common method for dealing with a cache miss is pretty straight forward- when the cache is checked for a value and it
+is stale or not present the value is regenerated. The flaw to this approach is that it can mean many different requests
+will see that cache miss at the same time and also attempt to regenerate the potentially expensive code. This in turn
+can use up system resources and even cause a cache stampede, which is a type of cascading failure where the system is
+placed under too much load to regenerate the cache which causes the load to further increase as more requests for the
+data are made.
+
+A good example of this is Javascript Minification. Minifying javascript is an expensive process, and for larger
+libraries can take a few seconds to occur (lets say five for this example). If a server receiving 30 requests a second
+for a javascript file that is hidden behind a minifier and there is a cache miss then there will be 30 requests the
+first second, 60 requests generating it the second, 90 the third, and ultimately by the fifth second there will be 150
+different requests regenerating the data. Unfortunately by this point the system load will also have risen considerably,
+making that five second processing time rise to higher and higher numbers.
+
Stampede Protection
===================
-Sometimes, when a cache item expires, multiple requests might come in for that
-item before it can be regenerated. If the process of generating it is very slow
-or expensive, these requests might stack up, each slowing down the system enough
-that previous requests can't complete -- this is a cache stampede. Stash has a
-stampede prevention function that's fairly easy to use:
+Stash refers to it's methods for preventing the Dog Pile Effect as Stampede Protection. These features are all ways to
+deal with stale data in such a way that only one request has to regenerate it. The default method is by triggering a
+single cache miss in advance so that a single process will regenerate the data before the data actually expires. There
+are other methods as well, such as reusing old values or simply disabling Stampede Protection altogether.
+
+Defining which method to use done by passing an Invalidation constant to the Item->get() class when it retrieves it's
+value. This tells the Item class how it should handle a miss, and what it should do while another class is processing
+data.
+
+The example below tells the Item class that it should switch from the default method of precomputing a value before it
+expires and that it should instead wait until the expiration and continue using stale values while another process
+regenerates the data.
.. code-block:: php
<?php
$item = $pool->getItem('Test');
- // Get the data from the cache using the "Item::SP_OLD" technique for
- dealing with stampedes
- $userInfo = $item->get(Stash\Item::SP_OLD);
+ // Get the data from the cache using the "Invalidation::OLD" technique for
+ // dealing with stampedes
+ $userInfo = $item->get(Stash\Invalidation::OLD);
// Check to see if the cache missed, which could mean that it either didn't
- exist or was stale.
+ // exist or was stale. If another process is regenerating this value and
+ // there is a stored value available then this function will return a hit.
if($item->isMiss())
{
// Mark this instance as the one regenerating the cache. Because our
- // protection method is STASH_SP_OLD other Stash instances will use the
- // old value and count it as a hit.
+ // protection method is Invalidation::OLD other Stash instances will
+ // use the old value and count it as a hit.
$item->lock();
// Run the relatively expensive code.
@@ -44,96 +69,91 @@ stampede prevention function that's fairly easy to use:
Invalidation Methods
====================
-Stash's stampede protection gives developers multiple ways to deal with stale
-data. Old values can be reused, new values set, or the cache can even be
-refreshed before it gets stale. Different methods can be set by passing the
-appropriate constant to Stash's "get" function.
+Stash's stampede protection gives developers multiple ways to deal with stale data. Old values can be reused, new values
+set, or the cache can even be refreshed before it gets stale. Different methods can be set by passing the appropriate
+constant to the Item::get function.
-None
-----
-By default Stash simply returns true for the "isMiss" function whenever the
-cache is invalid, meaning multiple cache misses can occur at once and stampede
-protection is not enabled. While not needed, this method can be explicitly set.
+Precompute
+----------
-.. code-block:: php
+The default behavior of Stash, this method causes Stash to recalculate the cached item *before* it misses. This reduces
+cache misses down to almost zero, as the only ones that occur are for new data or the arterial ones this creates.
- <?php
- // preserves backward compatibility.
- $item->get();
+When this method is used Item->get takes one additional argument, the amount of time (in seconds) before the expiration
+when it should regenerate the cache. If this isn't pass a default is chosen of 10% of the Item's TTL
- // recommended if this method is explicitly wanted as the default value may
- // change in the future.
- $item->get(Item::SP_NONE);
+.. code-block:: php
- // returns false if the item is missing or expired, no exceptions.
- $item->isMiss();
+ <?php
+ // five minutes before the cache expires one instance will return a miss,
+ // causing the cache to regenerate.
+ $item->get(Invalidation::PRECOMPUTE, 300);
-Precompute
-----------
-The personal favorite method of the Stash developers, this method causes Stash
-to recalculate the cached item _before_ it misses.
+None
+----
-When this method is used Stash->get takes one additional argument, the amount of
-time (in seconds) before the expiration when it should regenerate the cache.
+This removes stampede protection and provides no special behavior to limit multiple multiple cache misses. When a value
+is stale isMiss will always return true. This is useful for code that has special behavior on misses or that does not
+get called by a large number of users, such as by the Session Handler. Before Stash v0.12 this was the default behavior.
.. code-block:: php
<?php
- // five minutes before the cache expires one instance will return a miss,
- // causing the cache to regenerate.
- $item->get(Item::SP_PRECOMPUTE, 300);
+ $item->get(Invalidation::NONE);
+
+ // returns false if the item is missing or expired, no exceptions.
+ $item->isMiss();
+
Old
----
+----
-When this method is enabled and a different instance has called the lock
-function, Stash will return the existing value in the cache even if it is stale.
+When this method is enabled and a different instance has called the lock function, Stash will return the existing value
+in the cache even if it is stale.
.. code-block:: php
<?php
- $item->get(Item::SP_OLD);
+ $item->get(Invalidation::OLD);
- // return false if another Stash instance is rebuilding the cached item even
+ // return false if another Item instance is rebuilding the cached item even
// though the returned item is stale
$item->isMiss();
+
Value
-----
-When this method is enabled and a different instance has called the lock
-function Stash will return the supplied value.
+When this method is enabled and a different instance has called the lock function Stash will return the supplied value.
-This method takes one additional argument, the value to be returned while
-stampede protection is on.
+This method takes one additional argument, the value to be returned while stampede protection is on.
.. code-block:: php
<?php
- $item->get(Item::SP_VALUE, 'Return this if stampede protection stops a miss');
+ $item->get(Item::SP_VALUE, 'Use this value while regenerating cache.');
// returns true only if the value is stale and no other processes have
// stated rebuilding the value.
$item->isMiss();
+
Sleep
-----
-When this method is enabled and a different instance has called the lock
-function Stash will sleep and attempt to load the value upon waking up. This is
-not a website friendly method, but is potentially useful for cli or long running
+When this method is enabled and a different instance has called the lock function Stash will sleep and attempt to load
+the value upon waking up. This is not a website friendly method, but is potentially useful for cli or long running
scripts.
-When this method is used Stash->get takes two additional arguments, the time (in
-microseconds) to sleep before reattempting to load the cache and the amount of
-times to try and reload it before giving up. The maximum amount of time spent
-sleeping is the product of these two numbers.
+When this method is used Stash->get takes two additional arguments, the time (in microseconds) to sleep before
+reattempting to load the cache and the amount of times to try and reload it before giving up. The maximum amount of time
+spent sleeping is the product of these two numbers.
.. code-block:: php
<?php
- // sleeps for .5 seconds, reattempts to load the cache,
- // then sleeps again for another .5 seconds before making it's last attempt
- $item->get(Item::SP_SLEEP, 500, 2);
+ // sleeps for .5 seconds, reattempts to load the cache, then sleeps again
+ // for another .5 seconds before making it's last attempt
+ $item->get(Invalidation::SLEEP, 500, 2);
View
108 index.rst
@@ -6,6 +6,61 @@ Stash
Stash makes it easy to speed up your code by caching the results of expensive functions or code. Certain actions, like database queries or calls to external APIs, take a lot of time to run but tend to have the same results over short periods of time. This makes it much more efficient to store the results and call them back up later.
+Features
+========
+
+**Stores all PHP Datatypes**
+ Stash can store all of the php native datatypes- integers, booleans, null,
+ strings, arrays and objects that can be serialized.
+
+**Hierarchal Cache**
+ Stored items can be nested, like the folders of a filesystem. This allows
+ for related items to be groups together and erased when changed. Storing a
+ user's basic information can be nested 'users/userId/info', allow all of the
+ user's information to be removed quite easily.
+
+**Interchangeable Back Ends**
+ Stash can use a number of different storage engines to persist cache items
+ between requests. Current drivers include Filesystem, APC, Memcached, and
+ Sqlite drivers.
+
+**Staggered Drivers**
+ It occasionally makes sense to use multiple backends- for example, you may
+ have a small amount of memory to allot but a large piece of filesystem, in
+ which case using APC and the FileSystem driver together is an ideal
+ solution. Stash allows you to do this using the special backend,
+ MultiDriver, which can take an unlimited number of drivers.
+
+**Stampede Protection**
+ When a particularly expensive to generate item misses it can cause a chain
+ reaction- the system slows down as it generates the cache, but the longer it
+ takes the more processes that miss and start regenerating it. Stash gives
+ the developer the ability to limit cache regeneration to a single process,
+ as well as an assortment of ways to handle misses.
+
+**Regenerates Before Expiration**
+ Stash gives developers the option to regenerate a cached item before it
+ misses, making sure that up to data is always available while limiting
+ expensive code to running one instance at a time.
+
+**Distributed Cache Misses**
+ In order to reduce sudden spikes on a system Stash alters the expiration
+ times by lowering the cache age a random amount, thus distributing the cache
+ hits over a period of time.
+
+**Optimized Data Encoding**
+ Care is taken to use the fastest possible encoding and decoding functions
+ when storing data, with the preference being to store things in their native
+ data type. Serialization is reserved only for objects or deep
+ multidimensional arrays where breaking down each component individually
+ would be too long.
+
+**Comprehensively Unit Tested**
+ Every driver, class and wrapper is extensively tested. This includes using a
+ variety of datatypes and ranges in order to ensure that the data you put in
+ is the data you get out.
+
+
Example Usage
=============
@@ -75,59 +130,6 @@ Putting this together with the rest of Stash allows for a simple yet flexible wa
For an in-depth look at using Stash take a look at :doc:`Basic Usage <Basics>`
and :doc:`Drivers <Drivers>`.
-Features
-========
-
-**Stores all PHP Datatypes**
- Stash can store all of the php native datatypes- integers, booleans, null,
- strings, arrays and objects that can be serialized.
-
-**Hierarchal Cache**
- Stored items can be nested, like the folders of a filesystem. This allows
- for related items to be groups together and erased when changed. Storing a
- user's basic information can be nested 'users/userId/info', allow all of the
- user's information to be removed quite easily.
-
-**Interchangeable Back Ends**
- Stash can use a number of different storage engines to persist cache items
- between requests. Current drivers include Filesystem, APC, Memcached, and
- Sqlite drivers.
-
-**Staggered Drivers**
- It occasionally makes sense to use multiple backends- for example, you may
- have a small amount of memory to allot but a large piece of filesystem, in
- which case using APC and the FileSystem driver together is an ideal
- solution. Stash allows you to do this using the special backend,
- MultiDriver, which can take an unlimited number of drivers.
-
-**Stampede Protection**
- When a particularly expensive to generate item misses it can cause a chain
- reaction- the system slows down as it generates the cache, but the longer it
- takes the more processes that miss and start regenerating it. Stash gives
- the developer the ability to limit cache regeneration to a single process,
- as well as an assortment of ways to handle misses.
-
-**Regenerates Before Expiration**
- Stash gives developers the option to regenerate a cached item before it
- misses, making sure that up to data is always available while limiting
- expensive code to running one instance at a time.
-
-**Distributed Cache Misses**
- In order to reduce sudden spikes on a system Stash alters the expiration
- times by lowering the cache age a random amount, thus distributing the cache
- hits over a period of time.
-
-**Optimized Data Encoding**
- Care is taken to use the fastest possible encoding and decoding functions
- when storing data, with the preference being to store things in their native
- data type. Serialization is reserved only for objects or deep
- multidimensional arrays where breaking down each component individually
- would be too long.
-
-**Comprehensively Unit Tested**
- Every driver, class and wrapper is extensively tested. This includes using a
- variety of datatypes and ranges in order to ensure that the data you put in
- is the data you get out.
License
=======
Please sign in to comment.
Something went wrong with that request. Please try again.