views:

320

answers:

5

Just wondering how you would do this. Would you have some sort of process that scanned through all the actions that took place over the past X minutes? Would you trigger a badge update check every time any action took place (up vote, down vote, tag, etc.)? It seems like this would be a relatively expensive process one way or another.

+6  A: 

Perhaps a bit of both. I would probably queue up a check every time an action occurred and have a process that goes down the queue and determines if a badge has been earned for each check. This way it's semi-real time without causing pages to take more time to load. In fact, here on StackOverflow I've noticed a delay between when the badge is earned and when the system realizes it, so this site probably uses the same approach.

Kyle Cronin
Note that it actually is NOT real time on stack overflow - it took a couple of my badges a few page refreshes to show up.
Alex
SO uses a hack involving the server cache callbacks to kind of mimic a recurring task. It's discussed in one of the podcasts.
1800 INFORMATION
+1 I just realized that you could also calculate it on every action, but do it in a separate thread so as to not slow down site performance.
Kevin Pang
How many threads would you be spawning off if you did this on a separate thread? Each of these would be rather long-living... I can't imagine why you'd want to do this on every action. It should be a standard cron / recurring task to do the calculation for multiple users at once.
Alex
Just one thread. Each HTTP request thread will queue up a check in one central thread. The problem that I see with the cron approach is determining exactly what happened in the last 5 minutes. With this you have an exact record.
Kyle Cronin
A: 

I would personally have a cron job or similar that processed these on a regular basis. Probably on a "fake cron" flow system, where I'd have an invisible image call and go through the internal "cron stack" to see what needs to be done.

A lot of the badges however, shouldn't need that much to do with them... they should be able to be done with a nicely crafted query

Mez
Blank 1x1 images is so 2002. There are better ways in 2009, many of which are mentioned in this thread.
phidah
+2  A: 

I wouldn't trigger an update every time someone did an action; what I would do instead is a batch process that looks through every action performed in the last minute, sums things up with the "minute ago" state of every user, and gives out new badges based on that.

Alex
why all the negative votes?
Alex
+2  A: 

Use a database with 'hooks/triggers'. Then you can trigger an event on certain state changes, say for instance, you have a table that records every single up vote on a given answer.

You know that Answer > 10 Upvotes == "Good Answer", so you'd just put a trigger that occurs when LAST_STATE = 9 and NEXT_STATE = 10 and ENTRY_AWARDED_GOODANSWER = false.

Postgresql is one such database that supports such triggers.

Read more here: http://www.postgresql.org/docs/8.1/static/triggers.html

Kent Fredric
Would the transaction that updates the # of Up Votes be waiting while the trigger is executing? Or is the trigger execution asynchronous?
Alex
In postgres its MVCC. I don't understand how it works, but 2 people can be using the same rows and not have issues. Triggers /tend/ to happen as part of the triggering query, simply by doing the right command in the right trigger can cease the change happening.
Kent Fredric
+1  A: 

I'd probably use a Service Broker Queue in SQL Server to send actions onto the queue and activation procedure picks up the a bunch of actions at a time and runs it against a Badge checking procedure. A Badge Rules Engine for instance.

Coolcoder