Hi,
Here is a proposal for the solution of issue 8323. Alexandru, this mail is
mostly meant for you as you know the inner workings of ezcMail as well as I
do (or better). All opinions are welcome though..
The typical case when caching is needed for generating mail is when you have a
mail that is mostly similar but that changes one or two parts for each mail
sent out.
Case
-------
- Write some multipart mail with attachments. All the mail are the same except
for the text part where you substitute th
e "Dear mr. XXX" with the correct name from the database.
- Of course all mail should have a unique message id's.
Requirements
-------------------
- backwards compatible
- should preferably add caching on a low level so it doesn't need to be
implemented in each part
Discussion
--------------
Basically there are two approaches to solve this problem:
1. The user tells us which parts of the mail can not be cached
+ Caching can be implemented on the right MIME level since we know what can be
cached and what we can't cache when we generate.
- The user needs to be active in using the cache
2. A "dirty flag" system where each part knows if it is changed or not and we
can use cached parts of the mail based on that.
+ No user input needed
- All parts must implement functionality to make sure that they are
marked "dirty" when someone changes it.
- All MIME parts must always cache leading to a lot of overhead (which is what
we want to avoid with the cache system in the first place)
The overhead in option 2 is not acceptable (I think) so the rest of this
discussion is for option 1.
Observations:
- Leaf MIME nodes are the the ones that the user should set if they are
cacheable or not.
- Multiparts can not know if the are cacheable or not unless they ask their
subparts if they are cacheable.
Proposal
-----------
The proposal uses two new variables in ezcMailPart to control caching:
isCacheable - Set by the user to indicate to the caching system if the part
can be cached or not. By default this is set to true which means the part
will not change between each mail generated.
doCache - This property is set by multiparts and indicates to the part if it
should actually perform caching. This is used to make sure that no
unnecessary caching is performed.
Pseudo Code
----------------
/**
* property-write bool $isCacheable If this part can be cached.
* True for all parts by default. The property does not do
* anything for multiparts
* property bool $doCache set by parent MIME object (if any) to indicate if
this
* object actually needs to cache or not. True by default.
*/
class ezcMailPart
{
public function isCacheable()
{
return $this->isCacheable();
}
public function generate()
{
if( $this->doCache && cache_exists )
{
return cache;
}
else
{
// call generateHeaders() and generateBody()
// store cache
if( $this->doCache )
{
// store cache here...
}
}
}
}
For multiparts the situation is slightly different. Multiparts themselves must
check if the children are cacheable or not.
ezcMailMultiPart
{
public function isCachable()
{
foreach( $this->parts as $part )
{
if( $this->part->isCacheable() == false )
{
return false;
}
}
return true;
}
public generate()
{
foreach( $this->parts as $part )
{
if( $this->isCacheable() == true )
{
$part->doCache = false;
$part->generate();
}
}
}
}
This system has several advantages:
- It caches in the ezcMailPart class, so you get caching for free in all
subclasses
- Even if you override generate() and don't provide any caching at all it will
still work: if the parent MIME class can cache the result will be cached
there. If the part can't be cached it will just generate it's contents every
time.
Open questions:
- Do we want to have an option somewhere for a mail to turn caching on and
off? Where should it be? (it must be reachable for all parts) I say yes,
since generating multiple mail will behave different from the current
implementation (the parts will then be automatically cached and your changes
won't be seen). Which is a BC break.
- should isCacheable() be implemented as a read/write property but with logic
in the "__get" method?
Cheers,
Frederik
--
Components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/components