Skip to content

Instantly share code, notes, and snippets.

@markjaquith
Created August 16, 2011 19:33
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save markjaquith/1149945 to your computer and use it in GitHub Desktop.
Save markjaquith/1149945 to your computer and use it in GitHub Desktop.
TLC Transients — On the fly WordPress transients with soft expiration and one-liner chained syntax.
@scribu
Copy link

scribu commented Aug 16, 2011

Don't you think it's time to transform this into a proper git repo?

That way, you can use the fancy new ACE editor to edit files in the browser. ;)

@markjaquith
Copy link
Author

I only just put it up here! :-) Hadn't even told anyone about it yet. Yeah, it'll go into a proper GH repo soon! In the meantime, what do you think?

@scribu
Copy link

scribu commented Aug 16, 2011

It looks pretty neat. It could also be done via a one-time wp_cron job, no?

@johnbillion
Copy link

Would this be compatible with plugins that replace WordPress' cache with persistent cache systems like Xcache?

@scribu
Copy link

scribu commented Aug 16, 2011

Yep, since it only uses the transients API.

@prettyboymp
Copy link

Love it. It would be awesome to have the ability to sleep and try get the cached data again if the lock is already owned by another request for items that are required.

@aaroncampbell
Copy link

I'd honestly love to see this functionality in core. Until then though I'll test this out some in a couple of my plugins that could really use it.

@markjaquith
Copy link
Author

@scribu — yeah, it could have used a cron job. But cron jobs are annoying and flaky. I had an early version using cron jobs, but it wasn't as dependable. Also, the initial sync takes longer, because cron only runs once a minute.

@aaroncampbell
Copy link

What happens if the updates_with function can't get the data it needs? Like if it relies on a web service that's down? It seems that the data is still set, just set to null or false or whatever the updates_with function returns on failure. What do you think about allowing a way for that function to return something that will keep the data from being set? Maybe null or false, or even allow for an exception to be thrown?

@aaroncampbell
Copy link

Something like this:

try {
    $data = call_user_func_array( $this->callback, $this->params );
    $this->set( $data );
} catch( Exception $e ) {}

@retgef
Copy link

retgef commented Aug 30, 2011

Mark,

I'm working with a large site containing 4,000 videos (cpt). The client is asking to track hits on single videos within a two week period for use with displaying a "What's Popular Now" widget. What are your thoughts performance wise using a transient approach to track hits stored as such day->video_id->hits. Day transients would expire after two weeks. Thanks for the great writeup.

@markjaquith
Copy link
Author

@aaroncampbell — see the update. Like that?

@inspectorfegter — This should probably not be used for stuff that changes frequently. The way it works is that it essentially "forks" and runs each update in its own process. This is great for long-running updates that happen less frequently than once a minute. Transients should never be used as primary storage for any data, as they can go away at any time. For your hit counter, if it's not super-critical that the information be 100% accurate, you could store it in a transient and then write the transient value to a permanent storage location if the number of hits is divisible by 10, or 20, or 50, etc. That way you're not constantly writing to a permanent storage location. And if you unexpectedly lose the transient, you repopulate from the master, and at worst you lose the contents of the hit buffer.

@prettyboymp
Copy link

Wouldn't returning a WP_Error be more WordPress like for avoiding the cache update? Especially cases where you may normally receive a WP_Error result anyway.

Not only that, but if the update failed for whatever reason, not updating the timestamp on the current transient makes the site keep trying constantly. There needs to be a way to say don't try again for x-time when failing.

@retgef
Copy link

retgef commented Sep 1, 2011

Thanks Mark. That's exactly what I'm looking for.

@aaroncampbell
Copy link

@markjaquith - Yep, that's exactly what I did.

@prettyboymp - I suppose WP_Error would the "WordPress way". I feel like WP_Error is sort of the poor mans Exceptions because we weren't able to use Exceptions. I can see your point though, especially in the cases where you can do something like use wp_remote_request() directly with updates_with(). It means some errors are handled automatically by WordPress. However, not having your own function between the two means you can't handle things like empty (but successful) responses, invalid JSON or XML, etc.

As for a timeout for failed attempts, I suppose that would make sense but should probably be different from the expires_in, so you could set expires_in(30)->retry_in(5) to make it retry 5 minutes after a failed update and 30 minutes after a successful one.

@markjaquith
Copy link
Author

@aaroncampbellexpires_in() takes a seconds input, FYI. :-) I like the retry_in() idea.

@aaroncampbell
Copy link

@markjaquith - Yeah, my examples were bad...in my plugin I'm using it right though :-)

@markjaquith
Copy link
Author

Hey all. TLC Transients live here now: https://github.com/markjaquith/WP-TLC-Transients

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment