Tip:
Highlight text to annotate it
X
Okay, so Homework 6 solution:
I asked you to do a couple things.
I asked you to add to the bottom of the blog page
how long ago we ran the query--
and if we reload this page we can see this time incrementing--
and I also asked you to do this on permalink pages.
So if I were to look on a particular permalink,
I can see the age of its query,
and I can also tell when I create a new post--
create this new post--and when I submit it
I get redirected to a permalink page
whose query time increments,
and when I go back to the front of the blog,
I see my post on top with a nice, new low query time
and finally I asked you to implement a URL that clears the cache.
In mine, I called it flush, which just redirects right back to blog
but it resets the cache, which causes the query to run again.
So that's what I asked you to do, and now let's take a look at the code.
Okay. So the couple of things I needed to do:
I needed to use timedelta and datetime
to help compute the age of my posts,
and I also needed to import memcache just to cache things.
Now I added a bunch of functions that are kind of handy.
I added this one function called age_set
which basically is a wraparound memcache set,
but instead of setting just the value
it looks up the current time using datetime.utcnow,
and it stores that time along with the value in a tuple.
And then I made another function called age_get.
What this does is-- It's just like a memcache get,
but it returns both the value and the age of the item as a tuple.
So the first thing we do is we run the memcache.get on just the key.
If it exists, the value and the time we saved it are in R.
So we break those apart and then we compute the actual age in seconds,
which is we take the current time minus the time we saved it
and then we can call total_seconds on that,
which is a function that's included on timedelta.
Otherwise, if there's nothing in the cache, we just set val and age
to be none and zero respectively, and then we return them.
These are just handy functions, and I use them a couple places.
Now I've got a function that I run every time a new post gets submitted,
and this stores the post in the database,
and it takes an IP parameter which is unused.
I used to use this IP parameter on my previous antispamming version
so that you guys could still submit to the blog and see it working,
but it wouldn't store it in the database.
I was actually just storing it in memcached, and I got rid of that.
Now you just have to be logged in as me to submit to the blog.
It runs this get_posts function, which is defined here,
and this basically runs the database query
with update = True. You saw me do this in the lecture.
This is my technique for overwriting the cache with the new value.
Now, there's still erase conditions.
Remember we spent a lot of time talking about gets and casts?
I didn't use those here.
And then it returns the ID.
Get_posts--this is the function that runs the database query for me.
You saw me write something like this for ASCII Chan,
and here it is in the blog.
This is my query,
and I'm using the procedural language again to look up all the posts.
This is still an extra variable that's in there.
I don't remember why.
Code grows organically like that sometimes.
Here's the memcache key I'm using.
I'm just calling the string blogs.
I usually start a memcache key I'm using in a variable,
especially when I'm referencing it multiple times
in case I want to change it or just avoid typos and that sort of thing.
It's a good habit to get into.
So first I call age_get, which does the memcache lookup for that key
and gives me posts and the age,
and if update is true or posts is none--
so basically update is true or the posts aren't in the cache--
run the query, and then set mc_key to the value posts
and then return the age.
I've added another function called age_str,
which basically takes an age--
which in this point is a floating point of seconds--
and it returns the string replaced--
or queried--0 seconds ago, 1 second ago, that sort of thing.
So it converts it to an integer.
If the value is 1, we replace "seconds" with "second"
so it's grammatically correct, and then we return that string.
And I use this function in my templates
to print that string at the bottom of my pages.
And on my blog's front page, I call get_posts--
remember, this returns the posts and the age--
and I pass in the age to my template.
I convert age and I run the age_str function on it
so I can include it in my template--
and then on a permalink page we do something similar.
We cache each request.
So this is the key for our particular post.
It's the string post with post_id.
I usually prepend-- When I'm looking up by ID, I usually prepend a string
to the memcache key so that if I want to change it later I can just
change this string and everything expires.
We check to see if that post is already in the cache,
and if it is we have the age.
If it's not, we have to look it up from the database, and that's how we do it.
And then we set it to the cache, and we set the age to 0,
and then I return the permalink html,
My template now takes an age parameter, which is that age string.
So that's all the changes there. I'll show you the templates really quick.
Front that html.
It just has a new class at the bottom called age,
and that includes that age string that was passed in,
and permalink html has the same thing at the bottom--
a class called age with that string that we passed in.
And in our CSS file I added one little thing to the bottom,
which is this age class, and this says position absolute,
which basically says position this anywhere.
Zero pixels on the bottom. Zero pixels from the right.
Make it gray, and make the font size 12 pixels.
So that's how I put it, down in the lower right.
Obviously we're not gonna grade for that,
but that's just how I did it.
And that's the solution to Homework 6!
I hope you figured it out on your own.