What is meta? ×
Meta Stack Exchange is where users like you discuss bugs, features, and support issues that affect the software powering all 122 Stack Exchange communities.

A tremendous amount of effort and processing goes into casting a vote on SO. I am in the process of writing a similar system and I would like to know what were the most challenging technical aspects to implementing your system cleanly and reliably.

My observations thus far have led me to deduce the following:

  1. A vote requires a COUNT(*) query on daily votes to enforce voting limits.

  2. A vote requires retrieving the original post to validate: a) You are the question owner, if you are accepting the answer. b) You are not the post owner, if it's a mod vote. c) The age of the question, in order to accept an answer. d) The age of the question with a different criteria, if you are accepting your own answer. e) The post is also needed to determine the amount of reputation to update. 5 for a question and 10 for an answer in case of mod votes. 15 points in case of an accepted answer.

etc...

  1. The system must query to update the voter reputation, and numbers for modup/moddown votes.

  2. The system must query to update the question post if an answer is being accepted.

  3. The system must also query to update the reputation of the vote rcepient.

  4. A new vote record must be created.

  5. Changing an accepted answer must be a bit nightmarish for all the above reasons and crediting/deducting reputation, etc...

  6. Various decisions must be made on awarding badges,

All this must be done with transactions.

It seems like a frightening and daunting task. Are there any tips or things you learned from experience that can be helpful to someone trying to undertake the same task?

share|improve this question
    
Is there a question in there? –  raven Jan 31 '11 at 4:54
4  
@raven, yes: at the title, and the last paragraph. I think you are being harsh. I asked this on meta specifically because of the nature of the post. Is there anything wrong with wanting to learn about something I find challenging? I also did a lot of research to see how the process works on SO. I think that counts for something. –  Mohamad Jan 31 '11 at 5:06
add comment

1 Answer

up vote 1 down vote accepted
+50

I can't speak on behalf of the SO team—I have no knowledge of how any of the data is structured with the exception of the modified tables on SEDE. That said, it doesn't seem that daunting to me.

A vote requires a COUNT(*) query on daily votes to enforce voting limits.

Not necessarily. One could use a denormalized field in the Users table to check for the votes per day. A reputation recalc could take care of edge scenarios.

A vote requires retrieving the original post to validate: a) You are the question owner, if you are accepting the answer. b) You are not the post owner, if it's a mod vote. c) The age of the question, in order to accept an answer. d) The age of the question with a different criteria, if you are accepting your own answer. e) The post is also needed to determine the amount of reputation to update. 5 for a question and 10 for an answer in case of mod votes. 15 points in case of an accepted answer.

if(vote.voteType == AcceptVoteType){
  if(vote.voter == vote.voteTarget.Owner){
     vote.updateDatabase();
  } else {
     throw new SecurityException();
  }
}

if(vote.voteType.restriction == ModOnly){
  if(vote.voter.mod){
    vote.updateDatabase();
  } else {
    throw new SecurityException();
  }
}

// I'm not going to write out each one, but you get the idea.

The system must query to update the voter reputation, and numbers for modup/moddown votes.

vote.voter.addRep(vote.charge); // -1 for downvotes, 0 for all others

The system must query to update the question post if an answer is being accepted.

vote.voteTarget.parent.acceptedAnswer = vote.voteTarget;
vote.voteTarget.parent.updateDatabase();

The system must also query to update the reputation of the vote rcepient.

vote.voteTarget.owner.addRep(vote.award);    

A new vote record must be created.

INSERT INTO votes (voterID, targetId, voteType, etc...) VALUES (vote.voter.getID(), vote.target.getId(), vote.getVoteType())

Changing an accepted answer must be a bit nightmarish for all the above reasons and crediting/deducting reputation, etc...

vote.voteTarget.parent.removeAcceptedAnswer(){ // Just to look at the implementation
    // parent is the active object
    acceptedAnswer.owner.addRep(-AcceptedAnswer::award);      
    acceptedAnswer = null;
}
// use the code earlier to assign the new accepted answer

Warning: The code in this answer is all pseudocode and is designed to be proof-of-concept rather than actual implementation code. This code fails to demonstrate best practices such as encapsulation, so please don't use it in production (if it even compiles).

My advice: use OOP (all votes extend Vote, and adopt the KISS principle.

share|improve this answer
add comment

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .