[PRE-VOTE REVIEW] PSR Cache Proposal

678 views
Skip to first unread message

Paul Dragoonis

unread,
Mar 6, 2013, 8:21:05 PM3/6/13
to php...@googlegroups.com
Hey group,

The caching proposals have been open for the best part of a year now, we've been providing lots of revised implementations and had lots of discussions which we've had a vast amount of good feedback about. This email and effort from us guys involved is to bring closure and finalisation to this PSR Cache effort.

What we have here [1] now is the result of the long-term ongoing discussions and cache proposals that we have so far. The three open proposals were from Robert, Evert and Florin. Evert's and Florin's proposals have now been closed and superseded by this new proposal in an attempt to centralise our efforts into one main proposal now rathe than multiple forks.


What does this new proposal entail?
-----------------------------------------------
The good parts from all three proposals including the valid points raised from Robert's and his proposal. It's a merger and combination of all three previous proposals apart from one significant difference with Robert's proposal (detailed next) which is why his is still open.


What do we need to do?
-------------------------------
1) I'd appreciate it if everyone could review the text and the code interfaces on the proposal [1] and raise any final details missing with it. For small typos sentence restructuring you're welcome to use github for these type of small edits so not to spam this mailing list thread.

2) A vote on if they feel the cache driver instances being part of the primary Cache class [1] or being part of each child CacheItem class [2].

The vote can be a response to this email by saying,

In favour of:
Proposal 1: Yes or No
Proposal 2: Yes or No

This is not the official vote for if that PSR Cache proposal should be accepted but to give perspective over which one they think would be  better received by the FIG member projects.


Comparison with remaining proposal
-----------------------------------------------


Robert's proposal [2] is still open, the only significant and unique difference here is that

- On the joint effort proposal [1] the cache drivers such as Memcached or Redis instances/drivers are part of the main Cache class, so you can do something like:

$cache->set($key, $val)
or
$cache->remove($key)

This is just like you can with the existing Memcached and Redis instances available for PHP today.

- On the proposal from Robert [2] it has the connected driver from Memcached inside each individual child CacheItem classes rather than one copy of that in the main Cache class and you would do something like: 

$item = $pool->getItem($key); 
$item->setValue($val);
or
$item = $pool->getItem($key); 
$item->remove();

I hope this email was coherent enough for everyone, please ask me to clarify anything that was unclear or missing.


Thanks,
Paul Dragoonis


Robert Hafner

unread,
Mar 6, 2013, 8:53:26 PM3/6/13
to php...@googlegroups.com

I strongly disagree with the way the differences between these proposals was defined- I don't think it's nearly as clear as Paul is making it out to be.

I need some time to respond to this, as I was not involved in putting the "comprimise" or "combined" proposal. I'd appreciate it if people held off voting until I had a chance to explain what I feel are the pros and cons of each proposal. Unfortunately it may take me a day or two to do that, however I feel like that shouldn't be a big deal as we've been discussing this for about 14 months now.

Thanks,

Robert



--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Jeremy Lindblom

unread,
Mar 6, 2013, 9:55:21 PM3/6/13
to php...@googlegroups.com
I would like to hear Robert's side of this story as well.

In the meantime, I have quickly coded up sample Doctrine Cache adapters that would work with each of these proposed interfaces in order to help us compare the two. See https://gist.github.com/jeremeamia/5105190. If you see anything incorrect in my gist, let me know.

--
Jeremy Lindblom
PHP Software Development Engineer & Web Application Developer
Amazon Web Services – AWS SDK for PHP

@jeremeamia • https://github.com/jeremeamia

Beau Simensen

unread,
Mar 6, 2013, 10:34:45 PM3/6/13
to php...@googlegroups.com
On Wednesday, March 6, 2013 8:55:21 PM UTC-6, Jeremy Lindblom wrote:
I would like to hear Robert's side of this story as well.

I would as well.


In the meantime, I have quickly coded up sample Doctrine Cache adapters that would work with each of these proposed interfaces in order to help us compare the two. See https://gist.github.com/jeremeamia/5105190. If you see anything incorrect in my gist, let me know.

Wow, that is an interesting way to look at it. :) I honestly had not considered looking at it from that perspective, I thought you were going to write an implementation of each PSR-Cache proposal with a Doctrine Cache backing them.

From a quick pass I think this looks like you have written these correctly. One downside to this is highlighted in both cases as the `_doContains` is going to be less effective than either implementation will support. That is a nature of the limitation of Doctrine Cache, though, so not really anything we can do about that. At least I don't think we can. :)

Paul Dragoonis

unread,
Mar 7, 2013, 5:31:14 AM3/7/13
to php...@googlegroups.com
Cool idea to get perspective. Thanks Jeremy

Pádraic Brady

unread,
Mar 7, 2013, 6:43:43 AM3/7/13
to php...@googlegroups.com
Hi All,

Since this is just a straw poll, I'd urge everyone to hold off until Robert can respond in detail. I'd also suggest someone independent agree a new straw poll including agreed summaries from both sides - assuming they cannot reach a compromise proposal in the meantime.

I'm sure it was unintentional, but with Robert not being consulted beforehand and the poll being started by the proponent of one proposal, the risk of skewed results make this poll irrelevant.

Paddy

Paul Dragoonis

unread,
Mar 7, 2013, 6:49:08 AM3/7/13
to php...@googlegroups.com
On Thu, Mar 7, 2013 at 11:43 AM, Pádraic Brady <padrai...@gmail.com> wrote:
Hi All,

Since this is just a straw poll, I'd urge everyone to hold off until Robert can respond in detail. I'd also suggest someone independent agree a new straw poll including agreed summaries from both sides - assuming they cannot reach a compromise proposal in the meantime.

I'm sure it was unintentional, but with Robert not being consulted beforehand and the poll being started by the proponent of one proposal, the risk of skewed results make this poll irrelevant.

This isn't news, we've had lengthy discussions with Robert. The proposals could not be fully merged because Robert felt very strongly about the unique difference highlighted above in the original post so that's why I'm here to highlight the differences and give Robert the opportunity to show why he thinks his proposal is a better way of working.

I'm happy with either proposal going forward as long as there's consensus and our eyes are focused on one or two going forward.

Thanks!
Paul
 
--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/3Qs9COAWWs8J.

Pádraic Brady

unread,
Mar 7, 2013, 7:42:50 AM3/7/13
to php...@googlegroups.com
Hi Paul,

Understood. However, a straw poll is not an opportunity for further discussion. All I'm saying it that the poll results will be suspect. You and Robert should discuss a bit more with a view towards another poll (by all means, don't spend forever talking in circles!) by mutual agreement where both options have a say in the opening post.

Paddy

Florin Patan

unread,
Mar 7, 2013, 8:49:53 AM3/7/13
to php...@googlegroups.com
Hi Padraic,


I've tried to do the same thing as Paul did now a couple of months ago, in January I think.

Back then, I've merged my proposal with Evert's and Beau Simensen provided some great input back then as well.

When I've approached Robert he had the same arguments as now, with his proposal being better and that he's not interested in merging them. Also he said back then that he was independently working with a couple of other members from FIG to improve his proposal. Yet, no one else has stepped up to clarify some things since January, when I've asked them to come and help out with this and the proposal was left untouched since then aside from a couple of commits renaming two methods and some wording from Beau. So far Robert has proven to be unwilling to participate in a discussion to provide only a single, good, PSR for talking, and the example I've gave in January is just one of them.

Now Paul tried to step in and merged all three of them as he saw fit and me, Beau, Larry Garfield (I think, I can't remember, it was way back into the night when we did it) helped out in ironing out inconsistencies in the interfaces. 

I've did my fare share of input on Roberts proposal but so far he neither took the time to improve it or give good reasons why his proposal is truly better that anything else that we currently have. Others did the same. I hope this time he'll be able to provide feedback in the next days, as he said, and then we'll have a better image on this but consider that it would rather be good to start focusing on advantages / disadvantages on our (or better said, on your own - referring to voting members) and see this topic move along.

There's plenty of other things that will need attention in the future, Http Interface, Mails, Routing (maybe?) etc in my humble opinion.

If there's anything else that either us, those involved in caching proposals, or the voting member could do to make this an easier process do tell, I'd be happy to help out in any way, shape or form I can.




Best regards,
Florin

Paul Jones

unread,
Mar 7, 2013, 9:39:01 AM3/7/13
to php...@googlegroups.com

On Mar 6, 2013, at 8:21 PM, Paul Dragoonis wrote:

> Hey group,
>
> The caching proposals have been open for the best part of a year now, we've been providing lots of revised implementations and had lots of discussions which we've had a vast amount of good feedback about. This email and effort from us guys involved is to bring closure and finalisation to this PSR Cache effort.
>
> What we have here [1] now is the result of the long-term ongoing discussions and cache proposals that we have so far. The three open proposals were from Robert, Evert and Florin. Evert's and Florin's proposals have now been closed and superseded by this new proposal in an attempt to centralise our efforts into one main proposal now rathe than multiple forks.
>
> [1] New proposal: https://github.com/dragoonis/fig-standards/blob/master/proposed/psr-cache.md

I am going to ask the same thing that I ask of everything: how does the proposal match up with existing cache implementations in the member projects?


-- pmj

Beau Simensen

unread,
Mar 7, 2013, 10:06:08 AM3/7/13
to php...@googlegroups.com
On Thursday, March 7, 2013 7:49:53 AM UTC-6, Florin Patan wrote:
Back then, I've merged my proposal with Evert's and Beau Simensen provided some great input back then as well.

I think you did a great job trying to merge the proposals, Florin. As well as could be expected? I think this is why I see the following flow of maturity in the original three proposals:

Evert -> Florin -> Robert

By maturity, I don't mean to say any of the other proposals are "bad," I mean to say that Evert's is by far the simplest and Robert's is the most technically sound. The solution you worked on and that I helped with was somewhere in the middle. As it should have been. We made that a really good contender on its own. While I still think Robert's is better, we did a great job, as a group, polishing your proposal as a middle ground option that might very well have been voted in.

We did not need another attempt to merge these proposals. You had already done that.


Now Paul tried to step in and merged all three of them as he saw fit and me, Beau, Larry Garfield (I think, I can't remember, it was way back into the night when we did it) helped out in ironing out inconsistencies in the interfaces.

For the record, I was happy to help build this merged proposal but I did warn at the beginning that I did not think that the proposals could be merged in any meaningful way. I said right at the start that we would end up with something that was pretty much one of the existing proposals even though we started from scratch.

What we ended up with, as you yourself noticed, Florin, was basically Florin's proposal. The only thing of any substance that changed was that we made Florin's CacheItem mutable and gave the Cache the ability to set an existing CacheItem in addition to the set() method. We complicated an elegant and simple proposal (that we've been distilling for months) during an IRC discussion that lasted a few hours in order to "merge" proposals...

This is a clear case of http://xkcd.com/927/ and I even linked it at the beginning of our discussion on IRC.


I've did my fare share of input on Roberts proposal but so far he neither took the time to improve it or give good reasons why his proposal is truly better that anything else that we currently have. Others did the same. I hope this time he'll be able to provide feedback in the next days, as he said, and then we'll have a better image on this but consider that it would rather be good to start focusing on advantages / disadvantages on our (or better said, on your own - referring to voting members) and see this topic move along.

I've seen Robert give lots of reasons why his proposal makes sense. In particular I like his OO separation of concern angle. It makes a lot of sense to me. I'm looking forward to them being presented here again.


I'd like to point out that just prior to this whole notion of merging disparate cache proposals into one hybrid proposal we were starting to make real progress on refining the existing proposals. Robert's has been more or less solid for a long time and he went through the effort to make it simpler and remove the extension stuff. This was huge, in my opinion, and really changed the game. Florin's proposal had finally settled down to a concise proposal that had everything it needed and nothing more. I'd argue that the newest proposal we worked on actually harmed Florin's proposal by adding complexity that wasn't needed. It was better before it was merged. Evert's proposal isn't anywhere to be seen in the merged proposal. Is he actually onboard with the merge or has he abandoned his proposal altogether? I think he was basically backing Florin's proposal but I haven't heard his voice on this issue for awhile.

Please see this thread (started by Robert on February 25th) for a nice constructive presentation of the various proposals, the differences between them, and where they stand. This post was started by Robert, and some of us have spent a lot of time reviewing each proposal and looking at their strengths and weaknesses.



It was in doing the work to review these proposals that I was able to see that there was no real way to "merge" these concepts. It simply isn't possible. They are each very distinct approaches to the cache problem. For example, adding a cache item to Evert's proposal makes it no longer look anything like Evert's proposal and immediately either like Florin's or Robert's. You can't take "all of the work out of the CacheItem" from Robert's proposal without making it exactly Florin's proposal. I was saying these things as long ago as March 1st in the thread linked above:

After having seen Evert's proposal again, I have some comments on it as well. Most notably I'm finding myself more and more in favor of a "cache item" approach. So I'll try to keep this constructive as suggesting "please do it with a cache item?" means you'd basically be either writing Florin's proposal or Rober's. Or even Spring's. So I won't go there, 'k? :)


Long story short, I thought things were going really well up to the point that we had this notion of another merged proposal enter the mix. I mentioned on IRC that I thought that this was going to hurt the process. I hope this doesn't turn out to be the case. :-/ Things were really starting to feel good in Cache proposal land and now things are weird. It is very unfortunate.

Beau Simensen

unread,
Mar 7, 2013, 10:17:11 AM3/7/13
to php...@googlegroups.com
On Thursday, March 7, 2013 8:39:01 AM UTC-6, pmjones wrote:
I am going to ask the same thing that I ask of everything: how does the proposal match up with existing cache implementations in the member projects? 

I haven't done the research on it but I'd guess that Evert's is probably the closest match to most member projects. It is by far the simplest of the lot and as I said before, I feel there is a maturity progression from Evert's to Robert's proposal.

I liked the idea of having two cache proposals passed, a simple cache and an advanced cache. Some people are just going to want the dumb solution and not really worry or care about race conditions. Mostly because they've just been dealing with that since forever and "it works for me!" Other people need something more advanced and what some smarts to help protect their code.

If we only get to choose one, I'd vote to choose the better advanced cache even if the member projects right now are largely using a far more simple solution. It will help encourage member projects and other people alike to be smarter about handling cache. I can easily see people choosing to vote for Evert's just out of simplicity, though.

Jordi Boggiano

unread,
Mar 7, 2013, 10:31:04 AM3/7/13
to php...@googlegroups.com
Amen to all of this.

Cheers

--
Jordi Boggiano
@seldaek - http://nelm.io/jordi

guilher...@gmail.com

unread,
Mar 7, 2013, 10:34:43 AM3/7/13
to php...@googlegroups.com
Playing catch up on emails still... should comment on this thread soon. =)
Doctrine Cache is heavily affected by this PSR and I want to add my input.


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.





--
Guilherme Blanco
MSN: guilher...@hotmail.com
GTalk: guilhermeblanco
Toronto - ON/Canada

Paul Dragoonis

unread,
Mar 7, 2013, 10:38:54 AM3/7/13
to php...@googlegroups.com
Guilherme,

Pádraic Brady

unread,
Mar 7, 2013, 12:01:17 PM3/7/13
to php...@googlegroups.com
Hi Florin,

I'm not questioning past events nor will I discuss them or other people's opinions of yet other people's behaviour. I am simply stating that I have no confidence in the proposed straw poll. If there are irreconcilable differences between the two groups involved, then by all means hold a poll where both proposals have an even footing from the start so I can actually have some faith in the results.

Paddy

Robert Hafner

unread,
Mar 7, 2013, 12:40:49 PM3/7/13
to php...@googlegroups.com
Florin,

This email is a flat out lie. You and I literally spent hours talking in IRC. I asked you about submitting pull requests to mine, but you were deadset on making a third (and now fourth) proposal. Claiming that I never took the time to give you good reasons is literally a lie.

What ended up happening is that you ignored what I had to say, ran off with Paul when no one was around, and did your best to come up with a fake compromise that was just your proposal in disguise. This entire "poll" is just an underhanded tactic to force your proposal though, with the claim that there was compromise in IRC when you guys went out of your way not to include me in that discussion. By the time I was involved you guys didn't want to change anything, and said you were just going to throw it out to the list. Now you and Paul are trying to claim this is what compromise is.

As I said, I'm going to need a few days to respond to this. But I will say now that the entire process was a joke, and makes me respect this group far less. I've been working on my proposal for a year now. Evert's proposal was the first, and I offered to work on his but he wouldn't accept my PR's and told me to make my own. Even after I did that, I asked him if we could merge the two and he refused. I almost put the "Driver" into my proposal to cover what he's looking for, but was told it was a bad idea. So to claim I'm not trying to work with people is ridiculous. 

Then, after we spent a year working on refining my proposal, you came out of no where and decided to make a third one. You asked for input, and many people said you should contribute to mine. Instead you came up with your own, took a couple of my ideas but implemented them poorly due to lack of understanding, and sent it to the group. Now you and Paul have decided to take that proposal, clean it up a little, and present it to the group as a fourth proposal.

You're trying to claim here that I never took the time to work on your proposal. Yet how much time did you spend on mine? It seems like you're far more eager to get something passed that you wrote than you are to get something passed that's actually good. There is nothing stopping me from making the same claim you did- that you didn't help with my proposal. However, my proposal has been here for a year, has been torn about by tons of people, and has been a group effort. Your proposal is something you threw together last month. Paul's brand new proposal was something you guys threw together in a day, on IRC and without involving any of the original people who worked on caching. It also uses a lot of my base structure- why didn't you just submit a PR to mine that people could vote on, since you're using the same definitions but a different class structure? Oh, that's right, because then I'd actually be involved in the process and you couldn't claim it was your proposal that passed.

This entire process has been extremely frustrating, but it's made even more frustrating by the clique attitude with some members, the dishonest representation of what actually happened, and the fact that everyone wants to make their own proposal instead of working on the ones that are out there.


Robert




To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/sEnA7gdTKGsJ.

Paul Dragoonis

unread,
Mar 7, 2013, 1:03:19 PM3/7/13
to php...@googlegroups.com
Guys, please there's no need for all this fighting, ranting and bickering, it's only a couple of lines of PHP code!!

We have two proposals similar in fashion here, with some small differences. Robert when you have time can you outline the technical improvements that your proposal embraces so that things can be evaluated, we have all the code we need here.

Then we can progress with a final group decision which proposal is better suited for the first Psr\Cache release.

Thanks guys please relax :-)

Cheers,
Paul

Moisa Teodor

unread,
Mar 7, 2013, 2:18:59 PM3/7/13
to php...@googlegroups.com
Hi all,

I get the feeling that things are kind of rushed out. I've been following the conversations in this list pretty closely, and I get the feeling that there's some sort of unwritten deadline for this group to produce Psr\Cache. This is bad, because people will complain that they were not given the chance to speak their word and the level of hostility and negativity will increase.

Peace!

Pádraic Brady

unread,
Mar 7, 2013, 2:19:45 PM3/7/13
to php...@googlegroups.com
Final group decision being a vote by FIG members...

Robert, bear in mind that a straw poll is not binding on PHP-FIG if
that is the impression you're taking from this. It may assist in
gauging support but that is the only impact it can have, as a
popularity contest. I appreciate there can be a lot of frustration in
getting proposals through - we are slowly working on codifying a
workflow which will hopefully solve some of that and your input there
would be really welcome as someone who's going through such a process.
It should not be driving proposers into rants on the list - been
there, I had a jolly old rant about Zend when they moved to
squish/replace a proposal I had years ago for a Zend_OpenID component
so I tend to be a stickler for following a fair and open process.

Paddy

--
Pádraic Brady

http://blog.astrumfutura.com
http://www.survivethedeepend.com
Zend Framework Community Review Team
Zend Framework PHP-FIG Representative

Hari K T

unread,
Mar 7, 2013, 8:48:09 PM3/7/13
to php...@googlegroups.com
Hi Guys,

if you look into this thread, the second mail from Robert was to wait for a day or two .

And we all know he want to respond to it for things to move forward.

But there was a lot of mails and blaming people.

Let us stop blaming each other. We all are a family and trying to make things happen for the good. I know the frustration , but before we send a mail on the first read if things will not go right with that mail , please stop. ( May be I should stop writing this )

So my recommendation is if someone says stop : Please stop until the time they requested to clarify their stand. So no more mails to make this a huge thread.

@Robert : Even someone blamed don't write the whole frustrations to the group. You should learn from the PSR-2 thread ( the most hilarious proposal ? ) and how Paul M Jones dealt with it. I appreciate the way he made it to success. We need that way to make things move on.

And Paul Dragoonis was trying to push things only. We know this proposal was like dead and reborn . So you should actually appreciate him than blaming. As you know the fig is the authority to pass the proposal and the voting is not considered itself in members vote :P , and I appreciate Paddy making it clear as a voting member itself .

Probably we need a way of how we should reply into the thread .

ie once I said something we need to give room for everyones timezone . Else just 3 people can make the thread vast and if someone coming after a sleep seeing a bunch of mails is really bad and they will never read.  So a time frame to mail the second one to thread . I don't know whether the group has a feature like the one I mentioned.

Note : If we want to further discuss on things I said,  I think a new thread is good for this is for the vote and the difference. Sorry that myself writing after Robert said stop .

Jordi Boggiano

unread,
Mar 8, 2013, 4:24:25 AM3/8/13
to php...@googlegroups.com
On 07.03.2013 18:40, Robert Hafner wrote:
> As I said, I'm going to need a few days to respond to this. But I will
> say now that the entire process was a joke, and makes me respect this
> group far less.

I'll leave the accusations of this and that for the historians to sort
out. But this sentence is too much. The group did not do anything. If
anything most of the members shot down the straw vote because you didn't
have your say. Please don't blame "the group" when a couple persons
screw up (and I would hope it's more of an honest
mistake/misunderstanding on their part).

André R.

unread,
Mar 9, 2013, 6:44:58 AM3/9/13
to php...@googlegroups.com
On Thursday, March 7, 2013 4:17:11 PM UTC+1, Beau Simensen wrote:
I liked the idea of having two cache proposals passed, a simple cache and an advanced cache.

+1

But this means Robert needs to be on board to help make sure the simple proposal is future proof for the advance one(s).
Currently it doesn't seems like he is in on the kiss first approach.


If we only get to choose one, I'd vote to choose the better advanced cache even if the member projects right now are largely using a far more simple solution. It will help encourage member projects and other people alike to be smarter about handling cache. I can easily see people choosing to vote for Evert's just out of simplicity, though.


I'd still much prefer a modular approach.




 

Pádraic Brady

unread,
Mar 9, 2013, 7:23:02 AM3/9/13
to php...@googlegroups.com
This would go a lot easier if we bore in mind the facts. The group has
no workflow bylaw or process. Blaming what occuring on the group is
therefore a valid point. Making valid points is not "too much". It may
have been packaged emotionally but that doesn't undo the point made.

Paddy

--
Pádraic Brady

http://blog.astrumfutura.com
http://www.survivethedeepend.com
Zend Framework Community Review Team
Zend Framework PHP-FIG Representative


> --
> You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
> To post to this group, send email to php...@googlegroups.com.

Paul Dragoonis

unread,
Mar 12, 2013, 8:16:07 AM3/12/13
to php...@googlegroups.com
Hey,

After a week of reviews, updates, patches to the proposal and it's related 'examples' files, I have issued the PR, which you can see here: https://github.com/php-fig/fig-standards/pull/96


Please use the mailing list to open discussions about this PR and only use github to point out typos and small things like that.

Cheers,
Paul

FGM at GMail

unread,
Mar 12, 2013, 9:54:57 AM3/12/13
to php...@googlegroups.com
I may have missed some discussion of this, but I think the
confirmation of the timezone of the Expiration was never really
specified and the spec might need to take this into account, possibly
by specifying that (as most likely expected), Expiration is expressed
as in the W3C Profile of ISO 8601. Or as seconds after the Epoch, or
whatever.

2013/3/12 Paul Dragoonis <drag...@gmail.com>:

Paul Dragoonis

unread,
Mar 12, 2013, 9:57:42 AM3/12/13
to php...@googlegroups.com
On Tue, Mar 12, 2013 at 1:54 PM, FGM at GMail <fgma...@gmail.com> wrote:
I may have missed some discussion of this, but I think the
confirmation of the timezone of the Expiration was never really
specified and the spec might need to take this into account, possibly
by specifying that (as most likely expected), Expiration is expressed
as in the W3C Profile of ISO 8601. Or as seconds after the Epoch, or
whatever.

The expiration time is the epoch timestamp.

FGM at GMail

unread,
Mar 12, 2013, 10:01:09 AM3/12/13
to php...@googlegroups.com
Makes perfect sense, but from reading the proposal, this is not
specified, is it ?

2013/3/12 Paul Dragoonis <drag...@gmail.com>:

Paul Dragoonis

unread,
Mar 12, 2013, 10:06:04 AM3/12/13
to php...@googlegroups.com

FGM at GMail

unread,
Mar 12, 2013, 10:09:27 AM3/12/13
to php...@googlegroups.com
Indeed, that's where it struck me that the example did not specify how
these data were actually expressed or represented, to make sure
implementations are interoperable:

To wit, the text says:
"
Expiration - The actual time when an item is set to go stale.

An item with a 300 second TTL stored at 1:30:00 will have an
expiration at 1:35:00.
"

I remember there were discussions regarding the format of these dates
some months ago, especially regarding the use of DateTime vs
timestamps, and I think the result (timestamps in seconds since the
Epoch) should be specified to avoid problems, as it was not obvious
choice when these discussions occurred, or they wouldn't have
occurred.

2013/3/12 Paul Dragoonis <drag...@gmail.com>:

Beau Simensen

unread,
Mar 12, 2013, 10:11:33 AM3/12/13
to php...@googlegroups.com
That is not the way I read either of the specs.

TTL is the seconds in which the item will live. Not a hard time. "the amount of time between when that item is stored and it is considered stale." In the other proposal it was slightly more clear as it could also be defined as a DateInterval. So for example, setting a TTL of 300 would result in up to 5 minutes in the cache.

Expiration, on the other hand, is a fixed epoch time. But that is only used internally and to be able to speak plainly in the spec about "expiration." It has no impact on the public API as I understand it. The public API only deals in TTL.

Beau Simensen

unread,
Mar 12, 2013, 10:13:01 AM3/12/13
to php...@googlegroups.com
In the other proposal it was slightly more clear

By that I mean that it was a little more clear the intention of the TTL since DateInterval shows more clearly that the intention of the TTL was to show a difference in time and not an actual timestamp. :) 

Paul Dragoonis

unread,
Mar 12, 2013, 10:25:16 AM3/12/13
to php...@googlegroups.com
Would someone like to update the Definitions/explanatory text making things more clear?
Providing it on the mailing list or in a gist is fine too.


To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/9PO5uU6IvqkJ.

Andrew Eddie

unread,
Mar 12, 2013, 8:09:20 PM3/12/13
to php...@googlegroups.com


On Tuesday, 12 March 2013 22:16:07 UTC+10, Paul Dragoonis wrote:
Hey,

After a week of reviews, updates, patches to the proposal and it's related 'examples' files, I have issued the PR, which you can see here: https://github.com/php-fig/fig-standards/pull/96


I'm happy with that approach. Thanks Paul et al for all the work you've put into it.

Regards,
Andrew Eddie 

Andrew Eddie

unread,
Mar 12, 2013, 9:31:31 PM3/12/13
to php...@googlegroups.com
Minor typo on the CacheInterface::get method. Should be:

@return CacheItemInterface

Regards,
Andrew Eddie
http://learn.theartofjoomla.comfree tutorials and videos on Joomla development

Paul Dragoonis

unread,
Mar 12, 2013, 9:36:13 PM3/12/13
to php...@googlegroups.com
Updated, thanks!


Andrew Eddie

unread,
Mar 12, 2013, 10:00:55 PM3/12/13
to php...@googlegroups.com
Just some thoughts on return types. For non-getter methods, could we look at throwing an exception on error and returning $this to allow for chaining?

For example:

    /**

     * Remove an item from the cache by its unique key

     *

     * @param string $key The unique cache key of the item to remove

     *

     * @return CacheInterface  Returns itself to support chaining.

     *

     * @throws \RuntimeException on error

     */

    public function remove($key);



Regards,
Andrew Eddie

--
You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/UkSWS48eEgo/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to php-fig+u...@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

Amy Stephen

unread,
Mar 12, 2013, 11:40:11 PM3/12/13
to php...@googlegroups.com
Two questions:

1. On the set method -- allow null for the $key since the cache class will likely create the key.

(I am okay with no $key for a set -- can live with a key, too, but it should at least allow null)

    /**
     * Persisting our data in the cache, uniquely referenced by a key with an optional expiration TTL time.
     *
     * @param string       $key   The key of the item to store
     * @param mixed        $value The value of the item to store
     * @param null|integer $ttl   Optional. The TTL value of this item. If no value is sent and the driver supports TTL
     *                            then the library may set a default value for it or let the driver take care of that.
     *
     * @return boolean
     */
    public function set($key, $value, $ttl = null);

2. The multiple set does not pass in keys.

Does that make sense for those who want the multiple?

Should it be consistent between the single and multiple sets?

Thanks!

Larry Garfield

unread,
Mar 13, 2013, 1:25:30 AM3/13/13
to php...@googlegroups.com
Section 1.3:

"By using the CacheItem, implementations will guarantee consistency across various systems and ensure that the user will always retrieve the expected data without performing any additional operations."

This sentence makes no sense to me.  Using an interface at all is intended to "guarantee consistency across various systems".  There's nothing obvious in CacheItem itself that makes that statement true.  Also, "without performing any additional operations" means... what?  No new IO?  No new method calls?  The sentence is too generic for me to get any meaning from it.

"The CacheItem objects are generated by the Cache class. CacheItem objects encapsulate the key and value of the stored cache entry"

This seems to imply that I as a consumer MUST NOT create CacheItem classes myself.  True?  If so, that should be made explicit.

Section 1.4:

"If the user does not provide a TTL value then the Cache MUST set a default value that is either configured by the user or, if not available, the maximum value allowed by the cache system. If the cache system does not support a TTL option then the user specified and default TTL values will be ignored."

Compound sentences make for holes in understanding. :-)  How is a default configured?  Also, "will be ignored" doesn't tell me anything as an implementer.  It is more written as if I were documenting how my implementation works to a user of an implementation.

I would reword this paragraph as follows:

"Implementations MAY provide a mechanism for a user to specify a default TTL if one is not specified for a specific cache item.  If no user-specified default is provided implementations MUST default to the maximum legal value allowed by the underlying implementation.  If the underlying implementation does not support TTL, the user-specified TTL MUST be silently ignored."

I *think* that says the same thing, but is (I think) more precise and leaves less room for implementers to make incompatible assumptions.

Also, this line: "It will be the implementation's job to define what values are considered valid or invalid for key names or TTL values based on what the underlying driver can accept but the user MUST be aware of the accepted values for both the TTL values as well as for key names."

That tells me as a user that I can make no assumptions whatsoever about what a legal key value is, and I'm entirely at the mercy of a given implementation.  That is, if a given implementation decided to only allow lower-case alphabetic keys up to 5 characters, that's spec-legal (even if a stupid implementation).  TTLs are already handled in the previous paragraph, so should not be mentioned here.  For keys, we should define at least a minimum baseline.  I'd recommend mandating that all implementations MUST support, at minimum, unaccented alphanumeric characters plus underscore in mixed case up to 32 characters long, in UTF-8 encoding (or compatible, since what I just described is also basic ASCII).  If a given implementation wants to also support full UTF-8 keys, or allow 64-character keys, or allow the infamous snowman character, cool.  But I as a user should be able to rely on at least that common baseline of UTF-8 alphanumerics.

Section 2.1:

I thought we were leaning toward offering both isHit() and isMiss()?  I'm fine either way with isMiss(), I don't much care, but I am surprised to not see it here after the previous thread.

Section 2.2:

The docblock for get() doesn't have a single-line opening.  The line that begins "A CacheItem object" should be separated from it to aid docblock parsing.  Also, "Here we pass in" sounds like a tutorial, not a documentation block.  It should be instead a more typical "Returns a whatever" style statement. Any further description belongs in the longdesc of the comment.  That applies to all methods in the specification. 

Also, please ensure all sentences end with periods.  Right now it's quite inconsistent throughout the document.

The description of $ttl on set() doesn't seem consistent with the text above.  I would see the docblock more as aimed at a consumer reading a text-tip in their IDE, not as a restatement of the intended behavior for implementors.  To that end, I'd suggest:

"The TTL value of this item, in seconds.  If not specified, it will default to the longest legal value or a previously-user-specified default value."

While not strictly required, I do think it would be good to allow DateInterval objects here as well.  It just feels subjectively more complete to allow *something* from PHP's fairly-well-developed date/time handling when talking about time.

We specify that getMultiple() must return a keyed array, which is good.  Should we also mandate the same order as the original $keys array, or explicitly NOT require that?  (We should do one or the other; I'd favor requiring it to match, but could see an argument either way as long as it's explicit.) 

getMultiple($keys); // $keys should be type-hinted to array

The $ttl parameter for setMultiple() should be written in plural.  Right now it's just a copy/paste of set(), so it reads awkwardly.

The various boolean returns are either not documented, or documented as "the result of the operation".  That tells me nothing at all.  If we're returning meaningful information, then it should be explicitly TRUE for a successful write or FALSE if the data could not be written.  If not, we should return $this to allow chaining.

Which, actually, brings up an interesting question.  Are there any exceptions we should be throwing here?  If not, should we document that exceptions must NOT be thrown?  Or that they MAY be thrown if the underlying implementation throws it?  (Eg, a DB cache throwing a PDOException.)  I'm not sure what the correct handling here is, but we should think through the failure conditions and how they should be treated so that implementers and clients can be consistent and know what to expect.

General thoughts:

On the whole I like this approach.  However, based on my conversation with Beau, Robert, Paul, et al in IRC last week I do want to call out one thing that was not included in the proposal here, because I think it's the key to the "Florian's vs. Robert's" question.

In some earlier versions, there was also a setItem() method on the Cache interface.  It accepted a CacheItem and a TTL, which in turn allowed for round-tripping of a CacheItem object. 

The important point there is that if CacheItem can be independently instantiated, it is completely unbound from the Cache implementation.  That means the CacheItem class is "dumb", and cannot contain any useful logic.

In Robert's version, the substantive distinction is that CacheItem is *not* created arbitrarily but instead spawned from the Cache object.  In Robert's vision, that allowed the CacheItem to be "smart" and do lazy-loading, because it could contain a reference to either Cache or to the underlying engine (DB connection, Memcache object, watever.)

In Robert's proposal he then put the meaningful methods on the CacheItem interface (to actually retrieve data).  However, if the CacheItem is spawned from the Cache object exclusively that is purely an API aesthetic question and not a change of functionality.  (The lazy-load behavior could still be implemented either way, just hidden behind an interface exactly as it should be.)  Personally I favor the general API model in the proposal on the floor now.

In the proposal in front of us, we have a CacheItem::setValue() method.  That... doesn't do anything as far as I can tell.  There is no Cache::setItem() method to accept a CacheItem to write, in which case the only way that CacheItem::setValue() would do anything is if it wrote back to the data store immediately.  However, that only works if CacheItem has a reference to Cache... which if it's not spawned from Cache in the first place it cannot have!  (Certainly not in a portable fashion.)

I believe there are two ways to address this problem.

1) Remove CacheItem::setValue(), and make CacheItem exclusively an immutable object returned by get()/getMultiple() for reading.  Period.  Make it clear that users will never be creating CacheItem objects themselves.  This approach has the advantage of simplicity.

2) Take a cue from Robert's proposal, and keep CacheItem::setValue().  We would then also need to add TWO methods to Cache:

// Sets a a cache item containing a key and value.
setItem(CacheItemInterface $item, $ttl)

// Returns a new CacheItem object, bound to the specified key.
createItem($key)

(We may also want a setMultipleItems(), or that could be tucked into the existing setMultiple(). I could go either way.)

What that allows for is:

// Warm a cache.
$items = $cache->getMultiple(array('foo', 'bar', 'baz'));
foreach ($items as $item) {
  if (!$item->isHit()) {
    $item->setValue(something_expensive());
    $to_save[] = $item;
   }
}
if ($to_save) {
  $cache->setMultipleItems($to_save);
}

// Create a new cache item objectively:
$item = $cache->createItem('foo');
$item->setValue(something_expensive());
$cache->setItem($item);

// As a side-effect, really, it also would allow for deferred fetching:
$item = $cache->get('foo');
if ($a && $b && $item->isHit()) {
  $value = $item->getValue():
  // Whatever
}

If $b returns false, then we never need to actually hit the cache implementation.  A given implementation can very easily lazy-check $Item, which means in the above code there is no IO to the cache system at all.  It's almost like Haskell's lazy-evaluation!  (OK, not really.)  That, I think, was Robert's biggest goal.  (Robert, I apologize if I'm misrepresenting this point but it's my understanding based on our conversation last week.)

What this approach offers is extensibility.  The current proposal (rightly, IMO) ignores more advanced questions such as tagging.  However, it's not obvious to me how either we or some other implementer could add that in a backward compatible way.  Modifying the method signature to set($key, $value, $ttl, $tags, $something_else) is clearly not workable.

Leveraging the CacheItem, though, makes that simple.  If a given implementation supports tagging, it would do so ONLY on setItem().  Like so:

$item = $cache->createItem('foo');
$item
  ->setValue(something_expensive())
  ->addTag('bob');
$cache->setItem($item);
$cache->set('bar', whaever()); // No tags allowed

// Later
$cache->clearByTag('bob');

This particular implementation extends CacheItemInterface with TaggableCacheItemInterface, and TagAwareCacheInterface.  It's completely backward compatible with non-tag-using code, however.  And, because CacheItem is only ever spawned by Cache, it can guarantee that it doesn't get an incompatible cache object back.  (Unless you have 2 cache implementations in place at once and pass an object back to the wrong one, in which case you are shooting yourself in the foot and it's not our problem.)

So my cache implementation can support all kinds of fanciness... on setItem() only.  If I want to use a 3rd party library that only speaks basic PSR-Cache, it will still work transparently because that library doesn't even need to know that it could use tagging.  It also means a PSR-Cache-Tagging spec would be just a few extensions to CacheItemInterface and CacheInterface, with no BC breakage.

I'm not suggesting we debate how to implement tagging or other features right now; However, given that we want to allow people to experiment and innovate on top of this model, and we want to be able to extend it ourselves in the future, I think building in the extra flexibility now to allow that to happen is worth the relatively modest extra effort now.  (For implementers not doing anything fancy with setItem(), it's a single line of code to have it defer to set().  Trivial.)

The other differences with Robert's proposal come down to "where to put the method" (I like them where they are in this proposal) or implementation details (the aforementioned "item contains the cache engine" question) that by design should *not* be part of the spec.  But the coupling of CacheItem to Cache is, I believe, valuable, and would allow both us and implementers far more leeway to experiment and extend in the future.

--Larry Garfield


On 03/12/2013 07:16 AM, Paul Dragoonis wrote:

Florin Patan

unread,
Mar 13, 2013, 3:59:29 AM3/13/13
to php...@googlegroups.com
Hi Amy,


See below

On Wednesday, March 13, 2013 5:40:11 AM UTC+2, Amy Stephen wrote:
Two questions:

1. On the set method -- allow null for the $key since the cache class will likely create the key.

(I am okay with no $key for a set -- can live with a key, too, but it should at least allow null)

    /**
     * Persisting our data in the cache, uniquely referenced by a key with an optional expiration TTL time.
     *
     * @param string       $key   The key of the item to store
     * @param mixed        $value The value of the item to store
     * @param null|integer $ttl   Optional. The TTL value of this item. If no value is sent and the driver supports TTL
     *                            then the library may set a default value for it or let the driver take care of that.
     *
     * @return boolean
     */
    public function set($key, $value, $ttl = null);

The $key is needed as you will want to find your item in cache.
Consider the following scenario: you want to save some information for productA and some information for userB.
If the CacheInterface implementation won't force you for a $key to be set, $key = null, and it would generate it auto-magically then you won't be able to retrieve that information by productA or userB.
 

2. The multiple set does not pass in keys.

Does that make sense for those who want the multiple?

Should it be consistent between the single and multiple sets?

Thanks!

Are you referring to this method?

/**
* Persisting a set of key => value pairs in the cache, with an optional TTL.
*
* @param array $items An array of key => value pairs for a multiple-set operation.

* @param null|integer $ttl Optional. The TTL value of this item. If no value is sent and the driver supports TTL
* then the library may set a default value for it or let the driver take care of that.
*
* @return boolean The result of the multiple-set operation
*/
public function setMultiple($items, $ttl = null);

Or you are referring to a certain demo implementation from Paul?

The reasoning from the above method is that it will allow you grouping of the same TTL items in a single call. I'm not sure it's the best way to handle it but the other option with array($key=>$value, $ttl => null/int) could be done as well, it just isn't consistent with the current common implementations, Memcached / APC, in terms of multiple items operations.

Hope this helps you.


Best regards,
Florin

Andrew Eddie

unread,
Mar 13, 2013, 5:48:26 AM3/13/13
to php...@googlegroups.com
I apologise in advance if these questions have been asked already.

1. CacheInterface::set returns a boolean. What would the difference be between true and false?

2. Is there a need to add a garbage collection like `clear` but it only clearing the expired cache items (more than one disk has filled up with a runaway cache)?

I'd also echo Larry's comment about CacheItem. Just thinking out loud, the following example be useful:

$item = $cache->get('foo');
if ($item->isMiss()) {
    $data = getDataMethod();
    $item->setValue('foo', $data, $ttl);
} else {
    $data = $item->getValue();
}
// Use $data

Could even go as extreme as:

$data = $cache->get('foo')->getValue($callback, $ttl);

Where the $callback is a data-getter to populate 'foo' if it's a miss.

Regards,
Andrew Eddie

Florin Patan

unread,
Mar 13, 2013, 5:59:08 AM3/13/13
to php...@googlegroups.com
Hi Larry,


Great input on the wording, I'll skip it from this reply, see below the rest of the comments:


On Wednesday, March 13, 2013 7:25:30 AM UTC+2, Larry Garfield wrote:
Section 1.3:

"By using the CacheItem, implementations will guarantee consistency across various systems and ensure that the user will always retrieve the expected data without performing any additional operations."

This sentence makes no sense to me.  Using an interface at all is intended to "guarantee consistency across various systems".  There's nothing obvious in CacheItem itself that makes that statement true.  Also, "without performing any additional operations" means... what?  No new IO?  No new method calls?  The sentence is too generic for me to get any meaning from it.

"The CacheItem objects are generated by the Cache class. CacheItem objects encapsulate the key and value of the stored cache entry"

This seems to imply that I as a consumer MUST NOT create CacheItem classes myself.  True?  If so, that should be made explicit.

You are right, there's no need for a user to create a CacheItem in the current implementation. Maybe in the future PSRs, PSR-Cache-Advanced, that will be allowed in order to enhance the CacheItem functionality but currently the users should be using the CacheItem only as a wrapper of the value from the cache system.
 

Section 1.4:

"If the user does not provide a TTL value then the Cache MUST set a default value that is either configured by the user or, if not available, the maximum value allowed by the cache system. If the cache system does not support a TTL option then the user specified and default TTL values will be ignored."

Compound sentences make for holes in understanding. :-)  How is a default configured?  Also, "will be ignored" doesn't tell me anything as an implementer.  It is more written as if I were documenting how my implementation works to a user of an implementation.

I would reword this paragraph as follows:

"Implementations MAY provide a mechanism for a user to specify a default TTL if one is not specified for a specific cache item.  If no user-specified default is provided implementations MUST default to the maximum legal value allowed by the underlying implementation.  If the underlying implementation does not support TTL, the user-specified TTL MUST be silently ignored."

I *think* that says the same thing, but is (I think) more precise and leaves less room for implementers to make incompatible assumptions.

Also, this line: "It will be the implementation's job to define what values are considered valid or invalid for key names or TTL values based on what the underlying driver can accept but the user MUST be aware of the accepted values for both the TTL values as well as for key names."

That tells me as a user that I can make no assumptions whatsoever about what a legal key value is, and I'm entirely at the mercy of a given implementation.  That is, if a given implementation decided to only allow lower-case alphabetic keys up to 5 characters, that's spec-legal (even if a stupid implementation).  TTLs are already handled in the previous paragraph, so should not be mentioned here.  For keys, we should define at least a minimum baseline.  I'd recommend mandating that all implementations MUST support, at minimum, unaccented alphanumeric characters plus underscore in mixed case up to 32 characters long, in UTF-8 encoding (or compatible, since what I just described is also basic ASCII).  If a given implementation wants to also support full UTF-8 keys, or allow 64-character keys, or allow the infamous snowman character, cool.  But I as a user should be able to rely on at least that common baseline of UTF-8 alphanumerics.

Do you think we should specify that currently, to ensure compatibility with most/all existing cache systems we should add a section that says that only ASCII alpha-numeric characters are allowed?
 

Section 2.1:

I thought we were leaning toward offering both isHit() and isMiss()?  I'm fine either way with isMiss(), I don't much care, but I am surprised to not see it here after the previous thread.

I thought that we are going for only one of them, can't remember which.
 

Section 2.2:

The docblock for get() doesn't have a single-line opening.  The line that begins "A CacheItem object" should be separated from it to aid docblock parsing.  Also, "Here we pass in" sounds like a tutorial, not a documentation block.  It should be instead a more typical "Returns a whatever" style statement. Any further description belongs in the longdesc of the comment.  That applies to all methods in the specification. 

Also, please ensure all sentences end with periods.  Right now it's quite inconsistent throughout the document.

The description of $ttl on set() doesn't seem consistent with the text above.  I would see the docblock more as aimed at a consumer reading a text-tip in their IDE, not as a restatement of the intended behavior for implementors.  To that end, I'd suggest:

"The TTL value of this item, in seconds.  If not specified, it will default to the longest legal value or a previously-user-specified default value."

While not strictly required, I do think it would be good to allow DateInterval objects here as well.  It just feels subjectively more complete to allow *something* from PHP's fairly-well-developed date/time handling when talking about time.

We specify that getMultiple() must return a keyed array, which is good.  Should we also mandate the same order as the original $keys array, or explicitly NOT require that?  (We should do one or the other; I'd favor requiring it to match, but could see an argument either way as long as it's explicit.) 

 
I'd favor for allowing implementations to return the keys in any order as long as they are ALL there. Sorting them in the input order would be a unnecessary waste of cycles imho.
 
getMultiple($keys); // $keys should be type-hinted to array

The $ttl parameter for setMultiple() should be written in plural.  Right now it's just a copy/paste of set(), so it reads awkwardly.

The TTL in setMultiple is applied to all the items and it's not an array, does it really make sense to have it as plural? (non-native English speaker here btw)
 

The various boolean returns are either not documented, or documented as "the result of the operation".  That tells me nothing at all.  If we're returning meaningful information, then it should be explicitly TRUE for a successful write or FALSE if the data could not be written.  If not, we should return $this to allow chaining.

I'd be more interested in the result of the operation rather that chaining so returning boolean would be the way to go if you ask me. Granted this should be documented a bit better/more clear.
 

Which, actually, brings up an interesting question.  Are there any exceptions we should be throwing here?  If not, should we document that exceptions must NOT be thrown?  Or that they MAY be thrown if the underlying implementation throws it?  (Eg, a DB cache throwing a PDOException.)  I'm not sure what the correct handling here is, but we should think through the failure conditions and how they should be treated so that implementers and clients can be consistent and know what to expect.


As mentioned above, a better documented boolean return type would be better imho.
Throwing exceptions just to signal that something went wrong is not a really good thing. Plus exceptions should be used for 'exceptional' cases when the program execution can't continue, at this is how I view them. In your example, with PDOException, that will be the implementing library job to catch the exception and return false when it occurred rather that send it to the upper level. Else we'll end up with having a boat load of exceptions that will need to be added to cover scenarios and so on and I think it's a bit of an overkill for something that should by default be lightweight - cache.
 
General thoughts:

On the whole I like this approach.  However, based on my conversation with Beau, Robert, Paul, et al in IRC last week I do want to call out one thing that was not included in the proposal here, because I think it's the key to the "Florian's vs. Robert's" question.

In some earlier versions, there was also a setItem() method on the Cache interface.  It accepted a CacheItem and a TTL, which in turn allowed for round-tripping of a CacheItem object. 

The important point there is that if CacheItem can be independently instantiated, it is completely unbound from the Cache implementation.  That means the CacheItem class is "dumb", and cannot contain any useful logic.

In Robert's version, the substantive distinction is that CacheItem is *not* created arbitrarily but instead spawned from the Cache object.  In Robert's vision, that allowed the CacheItem to be "smart" and do lazy-loading, because it could contain a reference to either Cache or to the underlying engine (DB connection, Memcache object, watever.)

In Robert's proposal he then put the meaningful methods on the CacheItem interface (to actually retrieve data).  However, if the CacheItem is spawned from the Cache object exclusively that is purely an API aesthetic question and not a change of functionality.  (The lazy-load behavior could still be implemented either way, just hidden behind an interface exactly as it should be.)  Personally I favor the general API model in the proposal on the floor now.

In the proposal in front of us, we have a CacheItem::setValue() method.  That... doesn't do anything as far as I can tell.  There is no Cache::setItem() method to accept a CacheItem to write, in which case the only way that CacheItem::setValue() would do anything is if it wrote back to the data store immediately.  However, that only works if CacheItem has a reference to Cache... which if it's not spawned from Cache in the first place it cannot have!  (Certainly not in a portable fashion.)

I believe there are two ways to address this problem.

1) Remove CacheItem::setValue(), and make CacheItem exclusively an immutable object returned by get()/getMultiple() for reading.  Period.  Make it clear that users will never be creating CacheItem objects themselves.  This approach has the advantage of simplicity.


In my proposal, which was later inspired by Spring, the item is just a wrapper for the values stored in cache. Since this was about making a simple to use/easy to enhance with a later version, I think we could drop the setValue().
On the other hand, there's nothing stopping you from implementing something like this: https://gist.github.com/dlsniper/216817a134f63b9a53c5
The problem is that you'll need to have yet another set of wrappers for existing systems in order to have all the interfaces same across CacheItem and Cache, see my Gist where I've added some comments. Those $this->driver calls would need then to be abstracted as well to provide a uniform way of doing the operations which is another layer which is not needed imho. If this is not clear enough, I can provide a full blown working example. That was the main difference between Evert's/my proposal and Robert's proposal.
 
What this approach offers is extensibility.  The current proposal (rightly, IMO) ignores more advanced questions such as tagging.  However, it's not obvious to me how either we or some other implementer could add that in a backward compatible way.  Modifying the method signature to set($key, $value, $ttl, $tags, $something_else) is clearly not workable.

Leveraging the CacheItem, though, makes that simple.  If a given implementation supports tagging, it would do so ONLY on setItem().  Like so:

$item = $cache->createItem('foo');
$item
  ->setValue(something_expensive())
  ->addTag('bob');
$cache->setItem($item);
$cache->set('bar', whaever()); // No tags allowed

// Later
$cache->clearByTag('bob');

This particular implementation extends CacheItemInterface with TaggableCacheItemInterface, and TagAwareCacheInterface.  It's completely backward compatible with non-tag-using code, however.  And, because CacheItem is only ever spawned by Cache, it can guarantee that it doesn't get an incompatible cache object back.  (Unless you have 2 cache implementations in place at once and pass an object back to the wrong one, in which case you are shooting yourself in the foot and it's not our problem.)

So my cache implementation can support all kinds of fanciness... on setItem() only.  If I want to use a 3rd party library that only speaks basic PSR-Cache, it will still work transparently because that library doesn't even need to know that it could use tagging.  It also means a PSR-Cache-Tagging spec would be just a few extensions to CacheItemInterface and CacheInterface, with no BC breakage.

I'm not suggesting we debate how to implement tagging or other features right now; However, given that we want to allow people to experiment and innovate on top of this model, and we want to be able to extend it ourselves in the future, I think building in the extra flexibility now to allow that to happen is worth the relatively modest extra effort now.  (For implementers not doing anything fancy with setItem(), it's a single line of code to have it defer to set().  Trivial.)


If you do however want to suggest things around a more advanced interface, you can do so with the preview here: https://github.com/dlsniper/fig-standards/blob/extended-cache-proposal/proposed/psr-extended-cache.md Just sayin' ;)

And you are right, extending the CacheItem should be the way of doing it.
If we look into the future, maybe a set/get/removeItem/s could be added in the future to support working with full CacheItems with no BC breaks to the current interface. I'll update the demo from above to provide a better picture.
That said, in the interest of simplicity, I think the current proposal covers both simple usage and future extensibility
 
The other differences with Robert's proposal come down to "where to put the method" (I like them where they are in this proposal) or implementation details (the aforementioned "item contains the cache engine" question) that by design should *not* be part of the spec.  But the coupling of CacheItem to Cache is, I believe, valuable, and would allow both us and implementers far more leeway to experiment and extend in the future.

I think current proposal, Paul's, allows for toying around with where to put your actual retrieval of the value, see the gist provided above, while still being consistent for the end-user. I'm not sure how this could affect interaction between various vendors, Doctrine and Zend for example being able to swap only the item/drivers (if this is really wanted).

Hope it helps.



Best regards,
Florin

Florin Patan

unread,
Mar 13, 2013, 6:22:35 AM3/13/13
to php...@googlegroups.com
Hi Andrew,


On Wednesday, March 13, 2013 11:48:26 AM UTC+2, Andrew Eddie wrote:
I apologise in advance if these questions have been asked already.

1. CacheInterface::set returns a boolean. What would the difference be between true and false?


It would the the result of the operation, if the item was written successfully in cache or not.
 
2. Is there a need to add a garbage collection like `clear` but it only clearing the expired cache items (more than one disk has filled up with a runaway cache)?


Garbage collection is a driver level problem. Aside from files, there's no way to tell memcached/apc (for example) as far as I know to remove the expired entries.
 
I'd also echo Larry's comment about CacheItem. Just thinking out loud, the following example be useful:

$item = $cache->get('foo');
if ($item->isMiss()) {
    $data = getDataMethod();
    $item->setValue('foo', $data, $ttl);
} else {
    $data = $item->getValue();
}
// Use $data

Could even go as extreme as:

$data = $cache->get('foo')->getValue($callback, $ttl);

Where the $callback is a data-getter to populate 'foo' if it's a miss.

So basically this would always return $data regardless of where it came from, cache or $callback, right?
It's an interesting approach.
Maybe we could have something like this in the 'PSR-Cache-Advanced' (or what ever would it be called) and have something like AdvancedCache::setMissCallback($callback) which could be triggered when there's a miss for the item.
What do you think? Would it make sense?


Best regards,
Florin
 

Regards,
Andrew Eddie

Florin Patan

unread,
Mar 13, 2013, 6:27:09 AM3/13/13
to php...@googlegroups.com
Just bouncing some ideas, we could have CallbackCacheItem::setMissCallback($callback) on the item instead which would be BC compatible as well.

Andrew Eddie

unread,
Mar 13, 2013, 7:25:16 AM3/13/13
to php...@googlegroups.com
On 13 March 2013 20:27, Florin Patan <flori...@gmail.com> wrote:
Just bouncing some ideas, we could have CallbackCacheItem::setMissCallback($callback) on the item instead which would be BC compatible as well.

Hrm.

$data = $cache->get('foo')->onMiss($callback)->getValue();

I'd be happy with that approach??

I would not hold this PSR up for it. There's no reason a PSR couldn't be proposed to address just *that* issue.

Regards,
Andrew Eddie

Paul Dragoonis

unread,
Mar 13, 2013, 8:40:43 AM3/13/13
to php...@googlegroups.com
Thanks guys for all the replies, I read everything.

Larry,
These introductory paragraphs were taken from the proposals that existed previously. 

Could you or someone write up a revised copy of them that makes more sense and conforms to the interfaces listed? 

What's the bonus reasons for making the CacheItemInterface objects immutable? This restricts people from updating a cache item's value and sending it back for persistence. I don't believe it's hindering implementation in any way but making mutable values more flexible for people to consume into their existing caching systems. I'd definitely be interested in hearing why immutable objects would be a better approach here.

Andrew / Florin,

I think an onMiss() method with a callback is valuable, but for our first proposal to get finalised and sent into the wild and most importantly learned lessons from, we could come back in a little while with the knowledge/experience gained and draft up a second caching PSR that builds on top of our first simple caching proposal.

I hope I covered everything.

Cheers,
Paul


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.

Amy Stephen

unread,
Mar 13, 2013, 9:00:19 AM3/13/13
to php...@googlegroups.com
OK, Florin on both counts. Got it.

It's working fine for me - implemented it into a cache class, no problems.

Thanks for everyone's work.

Moisa Teodor

unread,
Mar 13, 2013, 9:04:14 AM3/13/13
to php...@googlegroups.com
Hi all,

Regarding the onMiss() and events/callbacks in general, I think it should not be in the scope of the spec. An implementation could mix in an event dispatcher (ex. Événement or some future PSR-Events). 
--
Doru Moisa
web: http;//moisadoru.wordpress.com
tel: +40 720 861 922
Bucharest, Romania

Florin Patan

unread,
Mar 13, 2013, 9:17:19 AM3/13/13
to php...@googlegroups.com
Hi Paul,


See below:

On Wednesday, March 13, 2013 2:40:43 PM UTC+2, Paul Dragoonis wrote:
Thanks guys for all the replies, I read everything.

Larry,
These introductory paragraphs were taken from the proposals that existed previously. 

Could you or someone write up a revised copy of them that makes more sense and conforms to the interfaces listed? 

What's the bonus reasons for making the CacheItemInterface objects immutable? This restricts people from updating a cache item's value and sending it back for persistence. I don't believe it's hindering implementation in any way but making mutable values more flexible for people to consume into their existing caching systems. I'd definitely be interested in hearing why immutable objects would be a better approach here.

Currently there's no method that accepts an item, CacheItem, back in the Cache, so at least for the moment a mutable object doesn't make sense.
If we do allow for a model where the drivers can be injected into CacheItem and then the item does its magic, like in Robert proposal, then we'll need to have a setTtl() as well. I think this will complicate things unnecessarily for the moment.
After cleaning up the texts in the specifications maybe it will make sense have a vote on this as well?
 

Andrew / Florin,

I think an onMiss() method with a callback is valuable, but for our first proposal to get finalised and sent into the wild and most importantly learned lessons from, we could come back in a little while with the knowledge/experience gained and draft up a second caching PSR that builds on top of our first simple caching proposal.


This is right, both me and Andrew were on the same page with this, lets first get the basic thing going, lets ensure it's future proof, like Larry said, there are a bunch of things to consider that we might add in the future and lets keep this in mind when we go to next step ;)



Best regards,
Florin

Paul Dragoonis

unread,
Mar 13, 2013, 9:17:24 AM3/13/13
to php...@googlegroups.com
Moisa,

Seems reasonable :-)

Paul Dragoonis

unread,
Mar 13, 2013, 9:20:04 AM3/13/13
to php...@googlegroups.com
On Wed, Mar 13, 2013 at 1:17 PM, Florin Patan <flori...@gmail.com> wrote:
Hi Paul,


See below:

On Wednesday, March 13, 2013 2:40:43 PM UTC+2, Paul Dragoonis wrote:
Thanks guys for all the replies, I read everything.

Larry,
These introductory paragraphs were taken from the proposals that existed previously. 

Could you or someone write up a revised copy of them that makes more sense and conforms to the interfaces listed? 

What's the bonus reasons for making the CacheItemInterface objects immutable? This restricts people from updating a cache item's value and sending it back for persistence. I don't believe it's hindering implementation in any way but making mutable values more flexible for people to consume into their existing caching systems. I'd definitely be interested in hearing why immutable objects would be a better approach here.

Currently there's no method that accepts an item, CacheItem, back in the Cache, so at least for the moment a mutable object doesn't make sense.
If we do allow for a model where the drivers can be injected into CacheItem and then the item does its magic, like in Robert proposal, then we'll need to have a setTtl() as well. I think this will complicate things unnecessarily for the moment.
After cleaning up the texts in the specifications maybe it will make sense have a vote on this as well?

Seems like a sensible decision. I did have setItem(CacheItemInterface $item) before which kinda made mutable objects make sense but since we decided to drop that then making the cache item object immutable is a good suggestion.
 
 

Andrew / Florin,

I think an onMiss() method with a callback is valuable, but for our first proposal to get finalised and sent into the wild and most importantly learned lessons from, we could come back in a little while with the knowledge/experience gained and draft up a second caching PSR that builds on top of our first simple caching proposal.


This is right, both me and Andrew were on the same page with this, lets first get the basic thing going, lets ensure it's future proof, like Larry said, there are a bunch of things to consider that we might add in the future and lets keep this in mind when we go to next step ;)

+1 on this, everyone is on the same page.
 



Best regards,
Florin
 
I hope I covered everything.

Cheers,
Paul


On Wed, Mar 13, 2013 at 11:25 AM, Andrew Eddie <mamb...@gmail.com> wrote:
On 13 March 2013 20:27, Florin Patan <flori...@gmail.com> wrote:
Just bouncing some ideas, we could have CallbackCacheItem::setMissCallback($callback) on the item instead which would be BC compatible as well.

Hrm.

$data = $cache->get('foo')->onMiss($callback)->getValue();

I'd be happy with that approach??

I would not hold this PSR up for it. There's no reason a PSR couldn't be proposed to address just *that* issue.

Regards,
Andrew Eddie

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/qqot04i709QJ.

Florin Patan

unread,
Mar 13, 2013, 9:24:10 AM3/13/13
to php...@googlegroups.com
Hi,


See below


On Wednesday, March 13, 2013 3:04:14 PM UTC+2, Doru Moisa wrote:
Hi all,

Regarding the onMiss() and events/callbacks in general, I think it should not be in the scope of the spec. An implementation could mix in an event dispatcher (ex. Événement or some future PSR-Events). 


Like I've said, just bouncing ideas but yeah, not in the scope of the current specs.
Could be considered in the future as well.

Moisa Teodor

unread,
Mar 13, 2013, 9:44:09 AM3/13/13
to php...@googlegroups.com
Hi Florin,


Like I've said, just bouncing ideas but yeah, not in the scope of the current specs.
Could be considered in the future as well.

I would not consider it neither now, nor in the future. The cache interface/spec should only care about caching. Having everything mixed in at the interface/spec level is bad as it will only add clutter and will increase the confusion. Besides antipattern symptoms having the onMiss() implies that there should be an onHit(), or even onExpire(), onChange(), onDelete() etc. 

Also, if the interface/spec enforces a specific programming paradigm (in this case - the event driven programming paradigm), it will certainly not be adopted by member/non-member projects that have a different philosophy.

Paul Dragoonis

unread,
Mar 13, 2013, 10:10:11 AM3/13/13
to php...@googlegroups.com
On Wed, Mar 13, 2013 at 1:44 PM, Moisa Teodor <mois...@gmail.com> wrote:
Hi Florin,


Like I've said, just bouncing ideas but yeah, not in the scope of the current specs.
Could be considered in the future as well.

I would not consider it neither now, nor in the future. The cache interface/spec should only care about caching. Having everything mixed in at the interface/spec level is bad as it will only add clutter and will increase the confusion. Besides antipattern symptoms having the onMiss() implies that there should be an onHit(), or even onExpire(), onChange(), onDelete() etc. 

Also, if the interface/spec enforces a specific programming paradigm (in this case - the event driven programming paradigm), it will certainly not be adopted by member/non-member projects that have a different philosophy.

All cool but lets not get bogged down with future ideas and focus on what we have right now.

As far as implementations go, it seems solid and we just need to work on the intro/description texts on the proposal.
 

--
Doru Moisa
web: http;//moisadoru.wordpress.com
tel: +40 720 861 922
Bucharest, Romania

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.

Larry Garfield

unread,
Mar 13, 2013, 10:39:18 PM3/13/13
to php...@googlegroups.com
On 03/13/2013 04:59 AM, Florin Patan wrote:

That tells me as a user that I can make no assumptions whatsoever about what a legal key value is, and I'm entirely at the mercy of a given implementation.  That is, if a given implementation decided to only allow lower-case alphabetic keys up to 5 characters, that's spec-legal (even if a stupid implementation).  TTLs are already handled in the previous paragraph, so should not be mentioned here.  For keys, we should define at least a minimum baseline.  I'd recommend mandating that all implementations MUST support, at minimum, unaccented alphanumeric characters plus underscore in mixed case up to 32 characters long, in UTF-8 encoding (or compatible, since what I just described is also basic ASCII).  If a given implementation wants to also support full UTF-8 keys, or allow 64-character keys, or allow the infamous snowman character, cool.  But I as a user should be able to rely on at least that common baseline of UTF-8 alphanumerics.

Do you think we should specify that currently, to ensure compatibility with most/all existing cache systems we should add a section that says that only ASCII alpha-numeric characters are allowed?

I'd be fine with that as a baseline.  I don't think we should prohibit implementers from supporting more characters (I can easily see a lot of systems wanting to support multi-byte characters if they deal in non-European languages), but we should set a minimum threshold that all implementations must support, at minimum.  "ASCII alphanumeric" plus basic punctuation like underscore, dash, and period seems like a reasonable baseline that everyone should be able to support.


 

Section 2.1:

I thought we were leaning toward offering both isHit() and isMiss()?  I'm fine either way with isMiss(), I don't much care, but I am surprised to not see it here after the previous thread.

I thought that we are going for only one of them, can't remember which.

As long as we keep isHit(), I don't care enough about isMiss() to make a fuss either way.


We specify that getMultiple() must return a keyed array, which is good.  Should we also mandate the same order as the original $keys array, or explicitly NOT require that?  (We should do one or the other; I'd favor requiring it to match, but could see an argument either way as long as it's explicit.) 

 
I'd favor for allowing implementations to return the keys in any order as long as they are ALL there. Sorting them in the input order would be a unnecessary waste of cycles imho.

Then we should probably add something like:

"Users MUST NOT rely on the order in which cache items are returned, as no order is required of implementers."


getMultiple($keys); // $keys should be type-hinted to array

The $ttl parameter for setMultiple() should be written in plural.  Right now it's just a copy/paste of set(), so it reads awkwardly.

The TTL in setMultiple is applied to all the items and it's not an array, does it really make sense to have it as plural? (non-native English speaker here btw)

It currently says "The TTL value of this item."  It should, rather, be something like "The TTL value for all specified items."

Hm, and I just noticed that setMultiple() should also be type hinted to an array. :-)


The various boolean returns are either not documented, or documented as "the result of the operation".  That tells me nothing at all.  If we're returning meaningful information, then it should be explicitly TRUE for a successful write or FALSE if the data could not be written.  If not, we should return $this to allow chaining.

I'd be more interested in the result of the operation rather that chaining so returning boolean would be the way to go if you ask me. Granted this should be documented a bit better/more clear.

A meaningful and well-documented True/False return value is fine.


Which, actually, brings up an interesting question.  Are there any exceptions we should be throwing here?  If not, should we document that exceptions must NOT be thrown?  Or that they MAY be thrown if the underlying implementation throws it?  (Eg, a DB cache throwing a PDOException.)  I'm not sure what the correct handling here is, but we should think through the failure conditions and how they should be treated so that implementers and clients can be consistent and know what to expect.


As mentioned above, a better documented boolean return type would be better imho.
Throwing exceptions just to signal that something went wrong is not a really good thing. Plus exceptions should be used for 'exceptional' cases when the program execution can't continue, at this is how I view them. In your example, with PDOException, that will be the implementing library job to catch the exception and return false when it occurred rather that send it to the upper level. Else we'll end up with having a boat load of exceptions that will need to be added to cover scenarios and so on and I think it's a bit of an overkill for something that should by default be lightweight - cache.

Well, here's what we want to avoid:

try {
  $cache->set('foo', $bar);
}
catch (PDOException $e) {
  // Handle a DB error.
}

And now wire up an object with a memcache backend, which has an error... boom, you have an uncaught exception.

So we should do one of the following:

1) Explicitly state that implementations MUST NOT throw exceptions, and therefore MUST catch and handle any exceptions their underlying engines generate.

2) Provide a base interface that all implementations MUST throw, if they are going to throw an exception.  That can be a chained exception with whatever the underlying exception was; that's fine.  But I need to be able to do:

try {
  $cache->set('foo', $bar);
}
catch (CacheException $e) {
  // Do whatever
}

And have that not break if I change my implementation.  Subclasses of CacheException are fine, CacheException that chains on top of a PDOException is fine, but that catch statement needs to work.

I'd much prefer option 2, as it allows for robust error handling.  Returning FALSE tells me nothing useful.
I don't follow.  If you never call new CacheItem() yourself, and only call $cache->create(), then the CacheItem object is always coupled to the implementation.  No wrappers needed.


I'm not suggesting we debate how to implement tagging or other features right now; However, given that we want to allow people to experiment and innovate on top of this model, and we want to be able to extend it ourselves in the future, I think building in the extra flexibility now to allow that to happen is worth the relatively modest extra effort now.  (For implementers not doing anything fancy with setItem(), it's a single line of code to have it defer to set().  Trivial.)


If you do however want to suggest things around a more advanced interface, you can do so with the preview here: https://github.com/dlsniper/fig-standards/blob/extended-cache-proposal/proposed/psr-extended-cache.md Just sayin' ;)

Those are all specific implementations of more advanced features; and without a Cache::setValue(), it's not immediately obvious how any of them would work. :-)  What I am suggesting allows for experimentation in-the-wild of those more advanced features, *before* we try to standardize them. 

If we go with option 1 -- and make CacheItem immutable and remove setValue() -- then I'd rather see the first extension to the caching system be adding back in setValue() and create() as discussed above, rather than dropping in specific advanced features right off the bat.


And you are right, extending the CacheItem should be the way of doing it.
If we look into the future, maybe a set/get/removeItem/s could be added in the future to support working with full CacheItems with no BC breaks to the current interface. I'll update the demo from above to provide a better picture.
That said, in the interest of simplicity, I think the current proposal covers both simple usage and future extensibility
 
The other differences with Robert's proposal come down to "where to put the method" (I like them where they are in this proposal) or implementation details (the aforementioned "item contains the cache engine" question) that by design should *not* be part of the spec.  But the coupling of CacheItem to Cache is, I believe, valuable, and would allow both us and implementers far more leeway to experiment and extend in the future.

I think current proposal, Paul's, allows for toying around with where to put your actual retrieval of the value, see the gist provided above, while still being consistent for the end-user. I'm not sure how this could affect interaction between various vendors, Doctrine and Zend for example being able to swap only the item/drivers (if this is really wanted).

I'm pretty sure no one will be swapping out the cache implementation but not the cache item implementation, or vice versa.  I cannot see any sane reason to do so. :-)

--Larry Garfield

Larry Garfield

unread,
Mar 13, 2013, 10:49:38 PM3/13/13
to php...@googlegroups.com
On 03/13/2013 08:44 AM, Moisa Teodor wrote:
Hi Florin,


Like I've said, just bouncing ideas but yeah, not in the scope of the current specs.
Could be considered in the future as well.

I would not consider it neither now, nor in the future. The cache interface/spec should only care about caching. Having everything mixed in at the interface/spec level is bad as it will only add clutter and will increase the confusion. Besides antipattern symptoms having the onMiss() implies that there should be an onHit(), or even onExpire(), onChange(), onDelete() etc. 

Also, if the interface/spec enforces a specific programming paradigm (in this case - the event driven programming paradigm), it will certainly not be adopted by member/non-member projects that have a different philosophy.

Some form of "here's how to populate the data if it's not there" is a very useful feature, and it doesn't have to be made to look like an anti-pattern.  (I'd say a second optional param to Cache::get(), myself.)  I agree that tying it into an event dispatcher of some kind is WAY overkill, but as a simple callback it would be fine.  I pitched a similar idea for Drupal's caching system a while back but it never went anywhere because I got distracted; I'd LOVE to see something like that implemented.  That is likely a follow-up PSR, though, I agree.

--Larry Garfield

Larry Garfield

unread,
Mar 13, 2013, 10:58:23 PM3/13/13
to php...@googlegroups.com
On 03/13/2013 07:40 AM, Paul Dragoonis wrote:
> Thanks guys for all the replies, I read everything.
>
> Larry,
> These introductory paragraphs were taken from the proposals that
> existed previously.
>
> Could you or someone write up a revised copy of them that makes more
> sense and conforms to the interfaces listed?

Well some of them are still being discussed (see elsewhere in this
thread), but I'll file a PR for the ones I think are non-contentious.

> What's the bonus reasons for making the CacheItemInterface objects
> immutable? This restricts people from updating a cache item's value
> and sending it back for persistence. I don't believe it's hindering
> implementation in any way but making mutable values more flexible for
> people to consume into their existing caching systems. I'd definitely
> be interested in hearing why immutable objects would be a better
> approach here.

It's not that immutable is better; it's that almost-mutable is bad. :-)
Consider:

// This makes sense, and would be agnostic across implementations.
$item = $cache->get('foo');
$item->setValue($item->getValue() + 5);
$cache->setItem($item);

// This *may or may not* be agnostic across implementations.
$item = new CacheItem();
$item->setKey('foo')->setValue(whatever());
$cache->setValue($item);

Basically, making CacheItem mutable is only safe to do if we also
restrict access to its constructor, by providing a $cache->create()
method for the second case. Otherwise, the constructor becomes a de
facto part of the interface (because that's how you'd setup driver
references and such), which is bad.

So we can either make it immutable, *or* we can go all the way and make
it a mutable factory-supplied object. But we can't go half-way.

It looks like Florian wants to go with immutable. As noted in my
previous messages, I would prefer to go with the more robust approach as
it allows for more experimentation and innovation by implementers
without harming interoperability.

I know we're all eager to get this passed, but I'd like to hear from
more people on this question (including Robert, especially) before we
push the proposal to a vote.

--Larry Garfield

Larry Garfield

unread,
Mar 14, 2013, 12:02:49 AM3/14/13
to php...@googlegroups.com
On 03/13/2013 09:58 PM, Larry Garfield wrote:
> On 03/13/2013 07:40 AM, Paul Dragoonis wrote:
>> Thanks guys for all the replies, I read everything.
>>
>> Larry,
>> These introductory paragraphs were taken from the proposals that
>> existed previously.
>>
>> Could you or someone write up a revised copy of them that makes more
>> sense and conforms to the interfaces listed?
>
> Well some of them are still being discussed (see elsewhere in this
> thread), but I'll file a PR for the ones I think are non-contentious.

Hm. OK, I have a branch ready but for some reason GitHub won't let me
file a PR against your repo, just the several dozen other people with
forks of the repo. :-( No idea why.

Branch is here if you want to peruse and pull (or tell me why it won't
let me file a PR):

https://github.com/Crell/fig-standards/tree/cache-language

--Larry Garfield

Matthieu Napoli

unread,
Mar 14, 2013, 3:38:58 AM3/14/13
to php...@googlegroups.com
Hi


Le jeudi 14 mars 2013 03:39:18 UTC+1, Larry Garfield a écrit :

So we should do one of the following:

1) Explicitly state that implementations MUST NOT throw exceptions, and therefore MUST catch and handle any exceptions their underlying engines generate.

2) Provide a base interface that all implementations MUST throw, if they are going to throw an exception.  That can be a chained exception with whatever the underlying exception was; that's fine.  But I need to be able to do:

try {
  $cache->set('foo', $bar);
}
catch (CacheException $e) {
  // Do whatever
}

And have that not break if I change my implementation.  Subclasses of CacheException are fine, CacheException that chains on top of a PDOException is fine, but that catch statement needs to work.

I'd much prefer option 2, as it allows for robust error handling.  Returning FALSE tells me nothing useful.

 
IMO option makes way more sense since it *is* an exceptional situation when a cache write fails, just like when a DB query fails (that doesn't happen every day, and it needs actions taken). And as Larry said, the exception will provide informations on the error that a boolean can't. Going the boolean way looks a lot like procedural PHP.
And if using exception, It should be consistent for all Cache methods. If my cache server is down, I don't want to get a "miss" item, I want to have an exception since it's not a "cache miss" per say.

Paul Dragoonis

unread,
Mar 14, 2013, 9:17:58 AM3/14/13
to php...@googlegroups.com
It's a bug in github. They told simensen a workaround for it but I don't understand it yet. 

I've manually pushed in your changes Larry, thanks!

 


--Larry Garfield


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+unsubscribe@googlegroups.com.

Evert Pot

unread,
Mar 14, 2013, 9:26:21 AM3/14/13
to php...@googlegroups.com
> 1) Explicitly state that implementations MUST NOT throw exceptions, and therefore MUST catch and handle any exceptions their underlying engines generate.
>
> 2) Provide a base interface that all implementations MUST throw, if they are going to throw an exception. That can be a chained exception with whatever the underlying exception was; that's fine. But I need to be able to do:
>
> try {
> $cache->set('foo', $bar);
> }
> catch (CacheException $e) {
> // Do whatever
> }


Both of those suggestions are pretty terrible imho.

If there are specific situations where it makes sense to throw an exception and catch it.. we should define these situations.. Don't add a 'catch-all' exception which only purpose is to be ignored.

If the implementor of the cache library decides that certain underlying exceptions are safe to be ignored, the implementor must catch these and handle or ignore them. Only the implementor of the cache library knows which exceptions those are. If an unexpected exception is thrown, this must leak through to the consumer.

Evert





Beau Simensen

unread,
Mar 14, 2013, 2:07:08 PM3/14/13
to php...@googlegroups.com
Thanks for the great review, Larry. I think that it is good that more people are really digging into this particular proposal to help clean it up.

I'm still looking forward to Robert's input on this thread but I wanted to comment on a few of the differences between the proposals in the meantime. Your post reminded me that I've been thinking about this for awhile and wasn't sure if this was the right time or place to discuss them. I guess it is on both accounts. :)


On Wednesday, March 13, 2013 12:25:30 AM UTC-5, Larry Garfield wrote:
The other differences with Robert's proposal come down to "where to put the method" (I like them where they are in this proposal) or implementation details (the aforementioned "item contains the cache engine" question) that by design should *not* be part of the spec.  But the coupling of CacheItem to Cache is, I believe, valuable, and would allow both us and implementers far more leeway to experiment and extend in the future.

I think these are definitely the most controversial and key differences. :) I'd like to share my take on these differences and why I think they are important to  myself and other people.



I believe Robert has a lot of ideas he is going to share on the "where to put the method" question. I've heard a few and I thought one of the more compelling is how he described the whole OO separation of concerns angle on IRC. In his proposal there is a clear division between operating on the pool as a whole and operating on an individual item. This division was clarified in the proposal in the Key Concepts section[1].

Larry talked a lot about the item being mutable or immutable. My opinion is that if the item is mutable it should be alive and active, otherwise it should be immutable. Since Pau'ls item is more or less dead I feel like it should be immutable. It would simplify things a great deal and I'm not sure how much value we would lose. I've heard the argument that Item::setValue will allow for more interoperability. I've also heard that it allows for "object round trip."

Somewhat related, I feel like we are dangerously close to shipping an implementation of PSR\Cache\Item. This comes with problems to solve like, "will people try to create this on their own?" and questions of whether we should have a setItem method that accepts an Item again. (it has been out and in and out again already... this discussion swings back and forth a lot) Then we start talking about createItem as options and it all starts to get a lot more complicated than it needs to be.

Robert's proposal gets around all of these problems by only ever accessing anything relating to an individual item via... the item. This means in all cases (even just setting something the first time) you are always using the same interface to operate on an individual item. The pools only responsibilities are to get the item for you and remove all of the items from the pool.

It is simpler and a result of the clear separation of concerns between what the pool/cache should be doing and what the item should be doing.

I don't know if I've really done the whole OO separation of concerns bit justice. I'm hoping Robert can go into it and the benefits of "where to put the method" better than I can so I'll leave it at that for now. :)



On the question of "where to put the method" leaking implementation requirements like "where the cache engine lives," I think this is not an issue. If it makes sense to model the cache interface around the division of "cache as a whole" operations and "individual item" operations, let's do that. If that means that items inherently need to have a reference to the cache engine or pool, so be it. If it is the better model why is this a problem? To do it any other way we would be choosing the model based on potential implementation details.

I really feel like this is the main technical issue people have with Robert's proposal. I'm not sure why this particular implementation detail is so important. It is trivial to write an implementation of either interface, I would like to think we all agree on that? So in that case I say we should pick the interface that has a cleaner OO abstraction. :)

I can totally see how this is going to be a sticking point for many, though. Not everyone is going to agree. This is probably going to be the biggest issue to resolve and I don't see there being a compromise here. It is either going to be one way or the other. :-/

Side note: I've also heard the argument that it would be expensive to "copy" the cache engine to each item. If you're creating new unique instances of the cache engine in each item you're doing it wrong. There are less expensive ways to handle this. We shouldn't try to protect people from themselves at the expense of forcing an inferior interface on ourselves.



The only open question I have about Robert's proposal is how bulk sets will happen in a way that is more performant. Right now I don't see how that can be handled as simply as if the Cache was doing everything. I imagine this is going to be around getItems returning an Iterator that implements an interface to allow for setting the items in bulk. I hope he can chime in on this. :)



I started doing a naive implementation of the pieces that the two proposals had in common in a Doctrine Cache backed implementation[2] (it may be slightly out of date; it is a week or so old now) and I found that I really liked having the control over everything in the item when implementing Robert's interface. Paul's interface definitely felt simpler. It was a great exercise! I'd suggest people try writing an implementation of both from scratch and see how implementing each feels.

I think that Robert's proposal suffers from naming confusion and "looking backwards from what people are used to doing." Going by pmjones's philosophy I would guess he'd say that we shouldn't go with Robert's solution because it is nothing like anything any of the member projects use. I'm sure a lot of people think this makes sense and in general I agree.

However, I think this is an opportunity for us to come up with a really well thought out forward thinking cache implementation. Why go with the lowest common denominator or something in the middle when we can get something that will better stand the test of time? I'd rather we work out the details people have of the more mature solution so we will be less likely to be smacking our heads wishing we'd gone down that road in a year or so.



I am excited to see people paying so much attention to cache again. I'm encouraged that people are talking about this latest proposal but I'd love if more people would start looking more carefully at Robert's proposal and start discussing it more as well. :)



Paul Dragoonis

unread,
Mar 14, 2013, 2:23:28 PM3/14/13
to php...@googlegroups.com
Hey Beau,

I read most of this, but I did get a bit of "TL;DR syndrome" on it for now. Just to be clear, the CacheItem class is now immutable because the main Cache class does not handle re-persistence of CacheItem classes so it makes no sense to make it mutable for this first simple spec.

I hope that cleared a few things up.


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/kPRdCcd78hMJ.

Beau Simensen

unread,
Mar 14, 2013, 2:30:55 PM3/14/13
to php...@googlegroups.com
On Thursday, March 14, 2013 1:23:28 PM UTC-5, Paul Dragoonis wrote:
 I did get a bit of "TL;DR syndrome"
 
I'm not surprised. It seems like I'm always writing too much. :-(


Just to be clear, the CacheItem class is now immutable because the main Cache class does not handle re-persistence of CacheItem classes so it makes no sense to make it mutable for this first simple spec.

I know we've talked about whether setValue should be there or not a lot on IRC and I didn't think it was taken out as Larry was talking about it still yesterday. :) I don't follow GitHub commits very well and didn't see you removed it yesterday. Thanks for the clarification. :)

Paul Dragoonis

unread,
Mar 14, 2013, 2:34:49 PM3/14/13
to php...@googlegroups.com
Instead of checking the commits, just check the latest copy of what the proposal has, and it has no CacheItemInterface->setValue() :)


Cheers!
 

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/pcsGGx0AQk0J.

Amy Stephen

unread,
Mar 14, 2013, 3:51:08 PM3/14/13
to php...@googlegroups.com


On Thursday, March 14, 2013 1:07:08 PM UTC-5, Beau Simensen wrote:

I think that Robert's proposal suffers from naming confusion and "looking backwards from what people are used to doing." Going by pmjones's philosophy I would guess he'd say that we shouldn't go with Robert's solution because it is nothing like anything any of the member projects use. I'm sure a lot of people think this makes sense and in general I agree.

Actually, I think what you are attributing to Paul Jones's comment makes perfect sense to me. The goal, as I understand it, is to find ways to build in interoperability amongst existing software shared by (primarily) member projects. If the goal were to build the best new software given ideas shared by (primarily) member projects, that would be a different kettle of fish, as it were.

I added my own set of tl/dr reflections on interfaces, posting https://groups.google.com/forum/#!topic/php-fig/qJqs4HBJSUc because I agree some reflection for the future efforts in a good idea to learn from these experiences without interrupting the shine and package work needed to get Cache out.

Sounds like several of us have taken the interface and have been able to implement it. Unless there are problems someone is able to identify in trying to use it with their cache packages, I hope to see it move towards a member vote. That'll give FIG two interfaces to work with to see how interoperability are impacted positively.

Beau Simensen

unread,
Mar 14, 2013, 8:23:53 PM3/14/13
to php...@googlegroups.com

On Thursday, March 14, 2013 8:17:58 AM UTC-5, Paul Dragoonis wrote:
On 03/13/2013 09:58 PM, Larry Garfield wrote:
Hm.  OK, I have a branch ready but for some reason GitHub won't let me file a PR against your repo, just the several dozen other people with forks of the repo. :-(  No idea why.

Branch is here if you want to peruse and pull (or tell me why it won't let me file a PR):

https://github.com/Crell/fig-standards/tree/cache-language

It's a bug in github. They told simensen a workaround for it but I don't understand it yet. 

I've manually pushed in your changes Larry, thanks!

I just wrote about the workaround so that we can all reference it more easily. I'm sure it will continue to be a problem for fig-standards as there are a lot of forks.


I had this issue with both dlsniper and dragoonis repositories so for at least me neither of those two are currently selectable targets for sending a PR.

Larry Garfield

unread,
Mar 15, 2013, 11:36:22 PM3/15/13
to php...@googlegroups.com
On 03/14/2013 08:17 AM, Paul Dragoonis wrote:



On Thu, Mar 14, 2013 at 4:02 AM, Larry Garfield <la...@garfieldtech.com> wrote:
On 03/13/2013 09:58 PM, Larry Garfield wrote:
On 03/13/2013 07:40 AM, Paul Dragoonis wrote:
Thanks guys for all the replies, I read everything.

Larry,
These introductory paragraphs were taken from the proposals that existed previously.

Could you or someone write up a revised copy of them that makes more sense and conforms to the interfaces listed?

Well some of them are still being discussed (see elsewhere in this thread), but I'll file a PR for the ones I think are non-contentious.

Hm.  OK, I have a branch ready but for some reason GitHub won't let me file a PR against your repo, just the several dozen other people with forks of the repo. :-(  No idea why.

Branch is here if you want to peruse and pull (or tell me why it won't let me file a PR):

https://github.com/Crell/fig-standards/tree/cache-language

It's a bug in github. They told simensen a workaround for it but I don't understand it yet. 

I've manually pushed in your changes Larry, thanks!

Hm.  There were two commits, one that adjusted the descriptive language and one that tightened up the code comments.  It looks like only the first one was applied.  Can you double check?  (The docblocks need the same level of precision as the descriptive language, since they form a part of the spec and therefore are critical to interoperability.)

--Larry Garfield

Larry Garfield

unread,
Mar 16, 2013, 2:21:10 AM3/16/13
to php...@googlegroups.com
On 03/14/2013 01:07 PM, Beau Simensen wrote:

*snip*

> I think that Robert's proposal suffers from naming confusion and
> "looking backwards from what people are used to doing." Going by
> pmjones's philosophy I would guess he'd say that we shouldn't go with
> Robert's solution because it is nothing like anything any of the
> member projects use. I'm sure a lot of people think this makes sense
> and in general I agree.
>
> However, I think this is an opportunity for us to come up with a
> really well thought out forward thinking cache implementation. Why go
> with the lowest common denominator or something in the middle when we
> can get something that will better stand the test of time? I'd rather
> we work out the details people have of the more mature solution so we
> will be less likely to be smacking our heads wishing we'd gone down
> that road in a year or so.

I think this is a good target for another poll like the Focus one I did.
:-) Data++

I'll put something together for that momentarily.

--Larry Garfield

Markus Staab

unread,
Mar 16, 2013, 10:44:08 AM3/16/13
to php...@googlegroups.com
Hi!

What do you think about a `lazy` method, which takes a `$key` and a `Closure` which would be invoked when no cached value is found.
This simplifies client code to something like

```php
$cachedValue = $cache->lazy($key, function() {
  // impl whatever should be done on cache miss
  // the returned value will be set into the CacheItem and also returned by `lazy()`
}, $ttl = null);
```

This also reduces the need for the always repeated cache pattern

```php
$item = $cache->get($key);
If(!$item->isHit()) {
  // do stuff
  $cache->set($key, $value);
} else {
  $value = $item->getValue();
}
```

So the implementation of the lazy method would look more or less like the pattern which is otherwise used all over the applications

Greets Markus aka @staabm

Am Donnerstag, 7. März 2013 02:21:05 UTC+1 schrieb Paul Dragoonis:
Hey group,

The caching proposals have been open for the best part of a year now, we've been providing lots of revised implementations and had lots of discussions which we've had a vast amount of good feedback about. This email and effort from us guys involved is to bring closure and finalisation to this PSR Cache effort.

What we have here [1] now is the result of the long-term ongoing discussions and cache proposals that we have so far. The three open proposals were from Robert, Evert and Florin. Evert's and Florin's proposals have now been closed and superseded by this new proposal in an attempt to centralise our efforts into one main proposal now rathe than multiple forks.


What does this new proposal entail?
-----------------------------------------------
The good parts from all three proposals including the valid points raised from Robert's and his proposal. It's a merger and combination of all three previous proposals apart from one significant difference with Robert's proposal (detailed next) which is why his is still open.


What do we need to do?
-------------------------------
1) I'd appreciate it if everyone could review the text and the code interfaces on the proposal [1] and raise any final details missing with it. For small typos sentence restructuring you're welcome to use github for these type of small edits so not to spam this mailing list thread.

2) A vote on if they feel the cache driver instances being part of the primary Cache class [1] or being part of each child CacheItem class [2].

The vote can be a response to this email by saying,

In favour of:
Proposal 1: Yes or No
Proposal 2: Yes or No

This is not the official vote for if that PSR Cache proposal should be accepted but to give perspective over which one they think would be  better received by the FIG member projects.


Comparison with remaining proposal
-----------------------------------------------


Robert's proposal [2] is still open, the only significant and unique difference here is that

- On the joint effort proposal [1] the cache drivers such as Memcached or Redis instances/drivers are part of the main Cache class, so you can do something like:

$cache->set($key, $val)
or
$cache->remove($key)

This is just like you can with the existing Memcached and Redis instances available for PHP today.

- On the proposal from Robert [2] it has the connected driver from Memcached inside each individual child CacheItem classes rather than one copy of that in the main Cache class and you would do something like: 

$item = $pool->getItem($key); 
$item->setValue($val);
or
$item = $pool->getItem($key); 
$item->remove();

I hope this email was coherent enough for everyone, please ask me to clarify anything that was unclear or missing.


Thanks,
Paul Dragoonis


Johannes Schmitt

unread,
Mar 16, 2013, 11:06:09 AM3/16/13
to php...@googlegroups.com
You could consider either directly using/extending the PHP Option type or just copying it's API:
https://github.com/schmittjoh/php-option

Extension (instead of copying) has the benefit that it can be combined with other APIs that use the option type. Either way, it will empower the cache API user considerably.

Cheers
Johannes

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/LsgbUynd9dgJ.

Florin Patan

unread,
Mar 16, 2013, 11:19:03 AM3/16/13
to php...@googlegroups.com, schmi...@gmail.com
Hey,


@Markus:
That could be an option but I think that we could also wait a bit until we see what the vote that Larry is organizing right now tels us.
The current focus is to provide a simple to use library with extensibility in mind while there will be at least one more PSR which specifies more advanced features so this could be part of it.

@Johannes: 
I think this should be brought in to the vote that Larry is organizing right now.
The focus, up until now, is not very clear so the current proposals while they might not be inline with existing APIs don't depend on external things. Relying on a component that is not part of PHP itself to define a PSR should be addressed first as an issue then integrated into current proposed PSRs. Emulation/extension could be a solution but maybe this is something that a bylaw / reference guide for PSRs should address first. Again, this could be considered as well a solution for a more advanced PSR.

@All:
What do you think? Would it make sense to have some better guidelines on how PSRs should be written/structured and what dependencies, if any, are they allowed to introduce as well?
Also is there any way to get in contact with Robert? I understand that he said he needs two days to get a reply and a week has passed. I don't want to rush anything but I really don't want to see the pattern repeating itself again :)
Have a great weekend.



Best regards,
Florin

Larry Garfield

unread,
Mar 16, 2013, 1:06:46 PM3/16/13
to php...@googlegroups.com
I firmly believe that an interface-PSR should have no dependencies on
existing PHP libraries not under the auspices of FIG. (Dependencies on a
previous PSR are fine if appropriate in context.) However, I've no
problem with taking inspiration from anywhere we can find it. I really
really like the idea of inlining a callable for "how to generate this
cache value if it's not there already". Whether we do it as part of
this PSR and what the exact syntax of it is I'd say is open to
discussion, but I would love to see such functionality.

--Larry Garfield

Lukas Kahwe Smith

unread,
Mar 16, 2013, 1:11:40 PM3/16/13
to php...@googlegroups.com
I agree that it would open can of worms depending on non php-src/PSR code/interfaces. However if there is something we feel would advanced a given PSR, then it might be worth bringing whatever that may be into PSR in some form to make it possible to use it.

regards,
Lukas Kahwe Smith
sm...@pooteeweet.org



Larry Garfield

unread,
Mar 16, 2013, 1:15:05 PM3/16/13
to php...@googlegroups.com
On 03/16/2013 12:11 PM, Lukas Kahwe Smith wrote:
>
>> I firmly believe that an interface-PSR should have no dependencies on
>> existing PHP libraries not under the auspices of FIG. (Dependencies
>> on a previous PSR are fine if appropriate in context.) However, I've
>> no problem with taking inspiration from anywhere we can find it. I
>> really really like the idea of inlining a callable for "how to
>> generate this cache value if it's not there already". Whether we do
>> it as part of this PSR and what the exact syntax of it is I'd say is
>> open to discussion, but I would love to see such functionality.
> I agree that it would open can of worms depending on non php-src/PSR code/interfaces. However if there is something we feel would advanced a given PSR, then it might be worth bringing whatever that may be into PSR in some form to make it possible to use it.
>
> regards,
> Lukas Kahwe Smith
> sm...@pooteeweet.org

Precisely what I mean by "taking inspiration from anywhere we can find it."

--Larry Garfield

Markus Staab

unread,
Mar 16, 2013, 1:18:28 PM3/16/13
to php...@googlegroups.com
I also think that supporting such kind of functionality with a
external lib would not be a good idea.

Would love to get this easy shorthand - however the syntax finally
will be - into this psr or into one of the successors

Markus
> --
> You received this message because you are subscribed to a topic in the Google Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/topic/php-fig/UkSWS48eEgo/unsubscribe?hl=en.
> To unsubscribe from this group and all its topics, send an email to php-fig+u...@googlegroups.com.
> To post to this group, send email to php...@googlegroups.com.

Robert Hafner

unread,
Mar 16, 2013, 2:57:13 PM3/16/13
to php...@googlegroups.com, php...@googlegroups.com, schmi...@gmail.com
A personal emergency came up which took my attention- I'll do my best to respond on Sunday. I should mention that a few of my points have already been brought up inside this thread.

Robert
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/_OZdn3a_0y8J.

Pádraic Brady

unread,
Mar 17, 2013, 7:57:11 AM3/17/13
to php...@googlegroups.com, schmi...@gmail.com
Hi all,

I'll respond by Monday. I'll also try to get some ZF feedback from the
Zend\Cache maintainer. Is there any timeline on when the window for
feedback will close? (No workflow so this is impossible to tell).

Paddy

--
Pádraic Brady

http://blog.astrumfutura.com
http://www.survivethedeepend.com
Zend Framework Community Review Team
Zend Framework PHP-FIG Representative

Paul Dragoonis

unread,
Mar 17, 2013, 11:06:53 AM3/17/13
to php...@googlegroups.com, schmi...@gmail.com
On Sun, Mar 17, 2013 at 11:57 AM, Pádraic Brady <padrai...@gmail.com> wrote:
Hi all,

I'll respond by Monday. I'll also try to get some ZF feedback from the
Zend\Cache maintainer. Is there any timeline on when the window for
feedback will close?

We're not rushing it, but we're not standing still either.

It would be good to get some perspective on the zend approach and to see if that approach highlighted any missing functionality in these PSR\Cache interfaces.

Thanks Padraic!

Andrew Eddie

unread,
Mar 25, 2013, 8:18:05 PM3/25/13
to php...@googlegroups.com, schmi...@gmail.com
Paul, just wondering what the plan is for moving this forward?

Also, I'm just wondering if it's worth slipping in a CacheAwareInterface like we already have in Log.

Regards,
Andrew Eddie

Paul Dragoonis

unread,
Mar 25, 2013, 8:31:28 PM3/25/13
to php...@googlegroups.com, schmi...@gmail.com
Hi Andrew,


On Tue, Mar 26, 2013 at 12:18 AM, Andrew Eddie <mamb...@gmail.com> wrote:
Paul, just wondering what the plan is for moving this forward?

The cache discussions have been maturing for about a year now. I'm ready for a vote. There were some questions or statements made about zend framework cache stuff by Padraic which hasn't happened yet.

I'll take it now that no news is good news and call a vote this Friday coming if nobody has anything else that will mature the proposal further.
 


Also, I'm just wondering if it's worth slipping in a CacheAwareInterface like we already have in Log.

I agree with this, and we should try to have an Aware interface with each Psr proposal so that people can start injecting loggers and cachers in places. Good suggestion! I'm going to add it to the proposal.
 

Regards,
Andrew Eddie

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+u...@googlegroups.com.
To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/UPF1DZFpcE4J.

Paul Dragoonis

unread,
Mar 25, 2013, 8:35:50 PM3/25/13
to php...@googlegroups.com, schmi...@gmail.com
On Tue, Mar 26, 2013 at 12:31 AM, Paul Dragoonis <drag...@gmail.com> wrote:
Hi Andrew,


On Tue, Mar 26, 2013 at 12:18 AM, Andrew Eddie <mamb...@gmail.com> wrote:
Paul, just wondering what the plan is for moving this forward?

The cache discussions have been maturing for about a year now. I'm ready for a vote. There were some questions or statements made about zend framework cache stuff by Padraic which hasn't happened yet.

I'll take it now that no news is good news and call a vote this Friday coming if nobody has anything else that will mature the proposal further.
 


Also, I'm just wondering if it's worth slipping in a CacheAwareInterface like we already have in Log.

I agree with this, and we should try to have an Aware interface with each Psr proposal so that people can start injecting loggers and cachers in places. Good suggestion! I'm going to add it to the proposal.
 

Larry Garfield

unread,
Mar 26, 2013, 10:56:25 AM3/26/13
to php...@googlegroups.com
On 3/25/13 7:31 PM, Paul Dragoonis wrote:
> Hi Andrew,
>
>
> On Tue, Mar 26, 2013 at 12:18 AM, Andrew Eddie <mamb...@gmail.com
> <mailto:mamb...@gmail.com>> wrote:
>
> Paul, just wondering what the plan is for moving this forward?
> https://github.com/dragoonis/fig-standards/blob/master/proposed/psr-cache.md
>
>
> The cache discussions have been maturing for about a year now. I'm ready
> for a vote. There were some questions or statements made about zend
> framework cache stuff by Padraic which hasn't happened yet.
>
> I'll take it now that no news is good news and call a vote this Friday
> coming if nobody has anything else that will mature the proposal further.

I think the idempotent vs. factoried CacheItem was still outstanding. I
would rather have a clear consensus on that before we move to a vote
rather than "letting the vote sort it out." (I'd love to get another
unanimous approval on cache like we had on logging.)

> Also, I'm just wondering if it's worth slipping in a
> CacheAwareInterface like we already have in Log.
> cf
> https://github.com/php-fig/log/blob/master/Psr/Log/LoggerAwareInterface.php
>
>
> I agree with this, and we should try to have an Aware interface with
> each Psr proposal so that people can start injecting loggers and cachers
> in places. Good suggestion! I'm going to add it to the proposal.

Very much agreed on that being a common tactic. We should probably also
include a stock Trait as well, as we did with logging.

--Larry Garfield

Pádraic Brady

unread,
Mar 26, 2013, 12:02:52 PM3/26/13
to php...@googlegroups.com, php...@googlegroups.com, schmi...@gmail.com
I've let the Zend/Cache maintainer and CRTeam know so any feedback they raise I'll pass along. I'll poke them again on IRC later.

Paddy

Pádraic Brady

Markus Staab

unread,
Mar 26, 2013, 12:54:52 PM3/26/13
to php...@googlegroups.com
Hi!

Another addition which could fit into the proposal: $ttl support as unix timestamp and also as seconds from now, as the php builtin memcache adapter does:


Quote: 
Expiration time of the item. If it's equal to zero, the item will never expire. You can also use Unix timestamp or a number of seconds starting from current time, but in the latter case the number of seconds may not exceed 2592000 (30 days).       

Larry Garfield

unread,
Mar 26, 2013, 12:59:04 PM3/26/13
to php...@googlegroups.com
An int meaning either TTL or TTD is begging for confusion. I think we
discussed allowing DateInterval or DateTime previously, but ended up
just going with TTL seconds. I'm fine with that simplification.

--Larry Garfield
> --
> You received this message because you are subscribed to the Google
> Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to php-fig+u...@googlegroups.com.
> To post to this group, send email to php...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/php-fig/-/_VC0G2mGGXcJ.

Paul Dragoonis

unread,
Mar 26, 2013, 2:18:17 PM3/26/13
to php...@googlegroups.com
We follow the way of memcached or redis set.

->set($key, $val, 300) // alive for 5 minutes

If the text on the proposal needs updating please update this somehow, github is preventing people from forking my repo because of some kind of fork limit.

Thanks.



To post to this group, send email to php...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msg/php-fig/-/_VC0G2mGGXcJ.
For more options, visit https://groups.google.com/groups/opt_out.


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to php-fig+unsubscribe@googlegroups.com.

To post to this group, send email to php...@googlegroups.com.

Paul Dragoonis

unread,
Mar 26, 2013, 2:18:47 PM3/26/13
to php...@googlegroups.com
On Tue, Mar 26, 2013 at 6:18 PM, Paul Dragoonis <drag...@gmail.com> wrote:
We follow the way of memcached or redis set.

->set($key, $val, 300) // alive for 5 minutes

If the text on the proposal needs updating please update this somehow, github is preventing people from forking my repo because of some kind of fork limit.

Please update this somehow meant, make a 'gist' and send it to the list or something.

Beau Simensen

unread,
Mar 26, 2013, 2:33:45 PM3/26/13
to php...@googlegroups.com
On Tuesday, March 26, 2013 1:18:17 PM UTC-5, Paul Dragoonis wrote:
github is preventing people from forking my repo because of some kind of fork limit.

For anyone who missed it, here is the workaround for if you find you are unable to send a PR to the correct repository:


Although at this point this might fall under the blatant self promotion category, I'd like to make sure that especially PHP-FIG people are aware of this workaround since we are all likely to run into it time and time again for the php-fig/fig-standards repository. Please feel free to send people here if you ever get a complaint that someone is having a hard time sending a PR to your proposal.

Pádraic Brady

unread,
Mar 27, 2013, 3:49:00 PM3/27/13
to php...@googlegroups.com
Hi all,

My apologies for the delay, but work commitments kicked in and I
needed to get feedback from the other ZF CRTeam members.

Comments on the Cache Proposal by the ZF Team:

1. Can we define TTL to always be an integer and remove the "normally"
qualification that suggests this is optional and can be something
other than an integer?
2. Can we soften wording on Key definition to allow integers as a valid key?
3. Can we clarify in the standard whether CacheItemInterface objects
are immutable, i.e. Value Objects?
4. CacheItems are not accepted as Keys despite representing a keyvalue
pair which suggests CacheItems are immutable and must be discarded
after a single read in favour of potentially updated values. Standard
needs to reflect intended usage.
5. There are some concerns about the presence of a separate
CacheItemInterface but no overwhelming objections from the ZF team.

Other comments:

1. The introduction seems vague and confusing. The first paragraph
basically says that there are difference caching libraries. This is
obvious and shouldn't require stating. The second paragraph suggests
that a caching interface will solve these "problems". Having multiple
caching libraries in not a problem. I think this is a clear
misunderstanding on my part but that's what I read into it. We need to
be clear and explicit to the point of spelling it out why the
interfaces are a good thing for users of caching libraries, i.e. easy
substitution, adoption, and sharing between applications or, as we
call it around here, interoperability.

2. Definitions. I love Markdown but let's just use HTML definition
lists since Markdown does not support a specific syntax for that.

3. As earlier, is TTL "normally" an integer or "always" an integer.
We're missing an RFC 2119 keyword in there.

4. Key definition: "Implementing libraries are responsible for any
encoding or escaping required by their backends, but must be able to
supply the original key if needed." Clarify? What is the original key?
Unescaped or escaped form? Who tracks the original key? The user or
the backend which reads the user's mind to supply the original key?

5. CacheItem & Cache - should be added to definition list and then
explained in greater depth in their respective sections.

6. "By using the CacheItem, implementations can guarantee consistency
across various systems." How? Why? Most programmers will see an
additional object that complicates usage but there's no nod to that
concern or an explanation to put those users at ease.

7. Key rules: Why a 32 character limit? Why is regular expression
emphasised instead of plain fixed width font? The regular expression
and the list of characters appear to be mismatched. Where is the unit
test for the rule?

8. isHit: I'd support a matching isMiss() check but if support is
against that so be it ;).

9. CacheInterface: I can't read the method comments without scrolling
on this PC. Isn't there a maximum line length for non-wrapping
code/text we should be applying?

10. Should we treat code comments as being required reading to
understand the standard? If so, it should apply RFC 2119 and be as
explicit as possible to avoid ambiguity. Explicity will make you look
stupid for stating the obvious so saying that get() accepts a key
name, uses key name to construct CacheItem capable of retrieving cache
value is better than saying "Here we pass in a cache key to be fetched
from the cache." We're not fetching the key that we already know...
"The result of the delete operation" TRUE being success, right? I'm
being silly, but please state the obvious or some folk will swarm us
seeking clarification and arguing about intended meanings just for the
fun of it.

11. Why are expected arrays in arguments not typehinted as "array"???

12: "This will wipe out the entire cache's keys" Clarify? Is this the
"rm -Rf /" of the cache world?

13. Example for PsrCacheItem shows CacheItem having a setValue()
method not defined in the interface. The example doesn't actually send
anything back to a driver though so probably needs removal.

14. I'm loathe to include examples within a standard when the unit
tests are missing... Are they part of the standard? If not, remove and
post them independently as a sort of "Guidance" document. Let the
standard stand by itself.

That's everything. I think I'll go lie down now!

Best regards,
Paddy


--
Pádraic Brady

http://blog.astrumfutura.com
http://www.survivethedeepend.com
Zend Framework Community Review Team
Zend Framework PHP-FIG Representative


On 7 March 2013 01:21, Paul Dragoonis <drag...@gmail.com> wrote:
> Hey group,
>
> The caching proposals have been open for the best part of a year now, we've
> been providing lots of revised implementations and had lots of discussions
> which we've had a vast amount of good feedback about. This email and effort
> from us guys involved is to bring closure and finalisation to this PSR Cache
> effort.
>
> What we have here [1] now is the result of the long-term ongoing discussions
> and cache proposals that we have so far. The three open proposals were from
> Robert, Evert and Florin. Evert's and Florin's proposals have now been
> closed and superseded by this new proposal in an attempt to centralise our
> efforts into one main proposal now rathe than multiple forks.
>
> [1] New proposal:
> https://github.com/dragoonis/fig-standards/blob/master/proposed/psr-cache.md
>
> What does this new proposal entail?
> -----------------------------------------------
> The good parts from all three proposals including the valid points raised
> from Robert's and his proposal. It's a merger and combination of all three
> previous proposals apart from one significant difference with Robert's
> proposal (detailed next) which is why his is still open.
>
>
> What do we need to do?
> -------------------------------
> 1) I'd appreciate it if everyone could review the text and the code
> interfaces on the proposal [1] and raise any final details missing with it.
> For small typos sentence restructuring you're welcome to use github for
> these type of small edits so not to spam this mailing list thread.
>
> 2) A vote on if they feel the cache driver instances being part of the
> primary Cache class [1] or being part of each child CacheItem class [2].
>
> The vote can be a response to this email by saying,
>
> In favour of:
> Proposal 1: Yes or No
> Proposal 2: Yes or No
>
> This is not the official vote for if that PSR Cache proposal should be
> accepted but to give perspective over which one they think would be better
> received by the FIG member projects.
>
>
> Comparison with remaining proposal
> -----------------------------------------------
>
> [2] https://github.com/tedivm/fig-standards/blob/Cache/proposed/PSR-Cache.md
>
> email to php-fig+u...@googlegroups.com.

Paul Dragoonis

unread,
Mar 28, 2013, 11:02:37 AM3/28/13
to php...@googlegroups.com
Thanks Pardaic, I will get to to your list later today or tomorrow at the latest.

Pádraic Brady

unread,
Mar 28, 2013, 12:42:36 PM3/28/13
to php...@googlegroups.com
Who's this Pardaic chap? ;)

No hurry - have a good weekend.

Pádraic Brady

Larry Garfield

unread,
Mar 28, 2013, 10:33:58 PM3/28/13
to php...@googlegroups.com
On 03/27/2013 02:49 PM, P�draic Brady wrote:
> Hi all,
>
> My apologies for the delay, but work commitments kicked in and I
> needed to get feedback from the other ZF CRTeam members.
>
> Comments on the Cache Proposal by the ZF Team:
>
> 1. Can we define TTL to always be an integer and remove the "normally"
> qualification that suggests this is optional and can be something
> other than an integer?

Agreed.

> 2. Can we soften wording on Key definition to allow integers as a valid key?

I think the regex definition would allow for that, no? (Or rather, an
all-digit string.)

> 3. Can we clarify in the standard whether CacheItemInterface objects
> are immutable, i.e. Value Objects?

I still think that is up for debate. We need to go one way with it or
the other, but there's no consensus on which way to go. We kind of
stopped talking about it. :-(
It's not a 32 character limit (at least if it's using the language I
wrote that Paul merged.) It says that implementations may not have a
character limit LESS than 32 characters. If an implementation wants to
allow a 128 character key it can, but it cannot allow only a 16
character key. If that's not clear, it should be clarified.

I didn't write a test for the regex because my regex-fu is weak. Someone
needs to check me. :-)

> 8. isHit: I'd support a matching isMiss() check but if support is
> against that so be it ;).

I think the consensus on that was "I don't want to block this spec on
that bikeshed, so I can live with whatever". :-)

> 9. CacheInterface: I can't read the method comments without scrolling
> on this PC. Isn't there a maximum line length for non-wrapping
> code/text we should be applying?
>
> 10. Should we treat code comments as being required reading to
> understand the standard? If so, it should apply RFC 2119 and be as
> explicit as possible to avoid ambiguity. Explicity will make you look
> stupid for stating the obvious so saying that get() accepts a key
> name, uses key name to construct CacheItem capable of retrieving cache
> value is better than saying "Here we pass in a cache key to be fetched
> from the cache." We're not fetching the key that we already know...
> "The result of the delete operation" TRUE being success, right? I'm
> being silly, but please state the obvious or some folk will swarm us
> seeking clarification and arguing about intended meanings just for the
> fun of it.

IMO, yes, the comments should be considered part of the spec. My PR had
another commit in it that Paul didn't merge that greatly cleans up the
interface docs, type hints, etc. I would strongly encourage that to get
merged, as it tidies up a LOT of the language:

https://github.com/Crell/fig-standards/commit/6172c896c452e399bbcb9ead199cdfcfe2efed82

> 11. Why are expected arrays in arguments not typehinted as "array"???
>
> 12: "This will wipe out the entire cache's keys" Clarify? Is this the
> "rm -Rf /" of the cache world?
>
> 13. Example for PsrCacheItem shows CacheItem having a setValue()
> method not defined in the interface. The example doesn't actually send
> anything back to a driver though so probably needs removal.

See above re immutable and the unmerged commit.

--Larry Garfield

Andrew Eddie

unread,
Apr 2, 2013, 8:22:07 AM4/2/13
to php...@googlegroups.com
On Friday, 29 March 2013 12:33:58 UTC+10, Larry Garfield wrote:
It's not a 32 character limit (at least if it's using the language I
wrote that Paul merged.)  It says that implementations may not have a
character limit LESS than 32 characters.  If an implementation wants to
allow a 128 character key it can, but it cannot allow only a 16
character key.  If that's not clear, it should be clarified.

I'm bumping into an issue when considering `setMultiple`:

// Is miss.
$results = $api->getAssociativeListOfResults();
$this->getCache()->setMultiple($results);

It's unlikely that my associative keys are 32 bytes so does that mean I have to reprocess the array to pad out the keys which feels like unnecessary double handling (and seems somewhat moot if we get to introduce namespacing). I'm not sure why we are forcing the developer to make up minimum length keys when you'd mostly be dealing with human-readable-esque keys anyway (eg "joomla.content.category.1") - it sounds like something the caching engine should do under the hood.

Regards,
Andrew Eddie

Beau Simensen

unread,
Apr 2, 2013, 10:53:55 AM4/2/13
to php...@googlegroups.com
On Tuesday, April 2, 2013 7:22:07 AM UTC-5, Andrew Eddie wrote:
 I'm not sure why we are forcing the developer to make up minimum length keys when you'd mostly be dealing with human-readable-esque keys anyway (eg "joomla.content.category.1") - it sounds like something the caching engine should do under the hood.

It is actually the cache implementation that has to worry about this. A developer would only have to worry if their key length excedes the underlying engine's maximum supported key length.


It says that implementations may not have a character limit LESS than 32 characters. If an implementation wants to allow a 128 character key it can, but it cannot allow only a 16 character key.

Emphasis is mine. Basically, it means that you, a developer, should be able to safely use the key "joomla.content.category.1" since at 25 characters it is less than the 32 minimum required key length that the implementation is required to support. It is up to the implementation to ensure that it supports at least a key length of 32 characters.

Is 32 characters a reasonable minimum length requirement? It seems pretty short to me. I don't know enough about key length restrictions on most of the cache engines so maybe this makes sense as-is.

Larry Garfield

unread,
Apr 2, 2013, 11:17:28 AM4/2/13
to php...@googlegroups.com
On 4/2/13 9:53 AM, Beau Simensen wrote:
> On Tuesday, April 2, 2013 7:22:07 AM UTC-5, Andrew Eddie wrote:
>
> I'm not sure why we are forcing the developer to make up minimum
> length keys when you'd mostly be dealing with human-readable-esque
> keys anyway (eg "joomla.content.category.1") - it sounds like
> something the caching engine should do under the hood.
>
>
> It is actually the cache implementation that has to worry about this. A
> developer would only have to worry if their key length excedes the
> underlying engine's maximum supported key length.
>
>
> It says that *implementations* may not have a character limit LESS
> than 32 characters. If an *implementation* wants toallow a 128
> character key it can, but it cannot allow only a 16character key.
>
>
> Emphasis is mine. Basically, it means that you, a developer, should be
> able to safely use the key "joomla.content.category.1" since at 25
> characters it is less than the 32 minimum required key length that the
> implementation is required to support. It is up to the
> *implementation* to ensure that it supports at least a key length of 32
> characters.
>
> Is 32 characters a reasonable minimum length requirement? It seems
> pretty short to me. I don't know enough about key length restrictions on
> most of the cache engines so maybe this makes sense as-is.

What Beau said. *Any* key up to 32 chars in length consisting of UTF-8
alphanumerics must be legal. So "foo", "bob", "123456", etc. are all
legal keys. If an implementation wants to be more permissive it can,
but it cannot be less permissive.

As for the specific length, I made up 32 kind of at random. I don't
really care what the actual minimum max-length is, but I think it's
important to have one.

--Larry Garfield

Andrew Eddie

unread,
Apr 2, 2013, 5:23:25 PM4/2/13
to php...@googlegroups.com
On 3 April 2013 01:17, Larry Garfield <la...@garfieldtech.com> wrote:
What Beau said.  *Any* key up to 32 chars in length consisting of UTF-8 alphanumerics must be legal.  So "foo", "bob", "123456", etc. are all legal keys.  If an implementation wants to be more permissive it can, but it cannot be less permissive.

As for the specific length, I made up 32 kind of at random.  I don't really care what the actual minimum max-length is, but I think it's important to have one.

Ok, thanks for clarifying.

Regards,
Andrew Eddie 

Paul Dragoonis

unread,
Apr 2, 2013, 10:03:10 PM4/2/13
to php...@googlegroups.com
I am still here. Workload is decreasing. Sorry for delays.


--

Paul Dragoonis

unread,
Apr 19, 2013, 8:41:10 AM4/19/13
to php...@googlegroups.com
I'm back. Sorry for the delays. Let me look at Padraic's comments and catch up.

Paul Dragoonis

unread,
Apr 22, 2013, 1:56:52 PM4/22/13
to php...@googlegroups.com
On Wed, Mar 27, 2013 at 3:49 PM, Pádraic Brady <padrai...@gmail.com> wrote:
Hi all,

My apologies for the delay, but work commitments kicked in and I
needed to get feedback from the other ZF CRTeam members.

Comments on the Cache Proposal by the ZF Team:

1. Can we define TTL to always be an integer and remove the "normally"
qualification that suggests this is optional and can be something
other than an integer?

Remove 'normally'
 
2. Can we soften wording on Key definition to allow integers as a valid key?

Any scalar value can be accepted really, you can pass in an integer no problem.
It will become a numerical string once to send it to your driver i.e: Memcached; http://php.net/manual/en/memcached.set.php
 
3. Can we clarify in the standard whether CacheItemInterface objects
are immutable, i.e. Value Objects?

CacheItemInterface objects are immmutable, there are no methods on that class to facilitate modifying values.
 
4. CacheItems are not accepted as Keys despite representing a keyvalue
pair which suggests CacheItems are immutable and must be discarded
after a single read in favour of potentially updated values. Standard
needs to reflect intended usage.

How? Where? You should update the text yourself rather than suggesting the text gets updated.
 
5. There are some concerns about the presence of a separate
CacheItemInterface but no overwhelming objections from the ZF team.

Other comments:

1. The introduction seems vague and confusing. The first paragraph
basically says that there are difference caching libraries. This is
obvious and shouldn't require stating. The second paragraph suggests
that a caching interface will solve these "problems". Having multiple
caching libraries in not a problem. I think this is a clear
misunderstanding on my part but that's what I read into it. We need to
be clear and explicit to the point of spelling it out why the
interfaces are a good thing for users of caching libraries, i.e. easy
substitution, adoption, and sharing between applications or, as we
call it around here, interoperability.

How would you improve it? Can you propose a revised paragraph(s)?
 

2. Definitions. I love Markdown but let's just use HTML definition
lists since Markdown does not support a specific syntax for that.

3. As earlier, is TTL "normally" an integer or "always" an integer.
We're missing an RFC 2119 keyword in there.

What RFC2119 keyword should be here ?
 

4. Key definition: "Implementing libraries are responsible for any
encoding or escaping required by their backends, but must be able to
supply the original key if needed." Clarify? What is the original key?
Unescaped or escaped form? Who tracks the original key? The user or
the backend which reads the user's mind to supply the original key?

I've removed the whole part about encoding.
 

5. CacheItem & Cache - should be added to definition list and then
explained in greater depth in their respective sections.

Added to definition list.
 

6. "By using the CacheItem, implementations can guarantee consistency
across various systems." How? Why? Most programmers will see an
additional object that complicates usage but there's no nod to that
concern or an explanation to put those users at ease.

7. Key rules: Why a 32 character limit? Why is regular expression
emphasised instead of plain fixed width font? The regular expression
and the list of characters appear to be mismatched. Where is the unit
test for the rule?

I changed this to a general recommendation.
 

8. isHit: I'd support a matching isMiss() check but if support is
against that so be it ;).

9. CacheInterface: I can't read the method comments without scrolling
on this PC. Isn't there a maximum line length for non-wrapping
code/text we should be applying?

10. Should we treat code comments as being required reading to
understand the standard? If so, it should apply RFC 2119 and be as
explicit as possible to avoid ambiguity. Explicity will make you look
stupid for stating the obvious so saying that get() accepts a key
name, uses key name to construct CacheItem capable of retrieving cache
value is better than saying "Here we pass in a cache key to be fetched
from the cache." We're not fetching the key that we already know...
"The result of the delete operation" TRUE being success, right? I'm
being silly, but please state the obvious or some folk will swarm us
seeking clarification and arguing about intended meanings just for the
fun of it.

Please provide a revised paragraph to resolve the problems you've highlighted. 

11. Why are expected arrays in arguments not typehinted as "array"???

So that you can pass in ArrayAccess or Traversable or array if you wish. You can't typhint against these.
 

12: "This will wipe out the entire cache's keys" Clarify? Is this the
"rm -Rf /" of the cache world?

Yes, it is. See apc_clear_cache() or memcached->flush()
 

13. Example for PsrCacheItem shows CacheItem having a setValue()
method not defined in the interface. The example doesn't actually send
anything back to a driver though so probably needs removal.


 

14. I'm loathe to include examples within a standard when the unit
tests are missing... Are they part of the standard? If not, remove and
post them independently as a sort of "Guidance" document. Let the
standard stand by itself.

The examples are there and will be removed and put into our official psr/cache package on packagist.
It is loading more messages.
0 new messages