Author Topic: Preventing Double Post  (Read 1680 times)

Offline CygnusX

  • Level 24
  • *
  • Posts: 303
  • Reputation: +3/-2
    • View Profile
    • Lords of Midnight
Preventing Double Post
« on: January 17, 2011, 11:11:48 AM »
Is there a way to prevent double posting on a URL?

Many of my form submissions now submit back to the page the user is on.  Aka, if on history, it will be <form method="post" action="history.php">

This is nice because it almost literally cuts my DB calls in half. 

However, if a user presses refresh, it 're-posts' the data... which I do not want.

Thanks.

Offline Nox

  • Level 35
  • **
  • Posts: 767
  • Reputation: +12/-2
    • View Profile
Re: Preventing Double Post
« Reply #1 on: January 17, 2011, 11:25:02 AM »
- Manually check the presence of identical entry in DB (extra DB call)
- Minimal time limit - cookie/session/whatever
...

I would still vote for redirect - if you're concerned about DB calls just use some caching

And you know - pressing 'refresh' makes the page load again too and with $_POST data so it actually costs more
Meet us at an IRC irc.freenode.net #bbg as well
https://vimeo.com/36579366 (a must-watch) | Join BOINC - no longer a hype, but you can help never the less

Offline Zeggy

  • Global Moderator
  • Level 35
  • *****
  • Posts: 1,187
  • Reputation: +13/-4
    • View Profile
Re: Preventing Double Post
« Reply #2 on: January 17, 2011, 11:25:49 AM »
After the form is processed, redirect the user.

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: Preventing Double Post
« Reply #3 on: January 17, 2011, 11:31:12 AM »
This is nice because it almost literally cuts my DB calls in half. 
If you mean performance then posting is irrelevant. You will get majority of hits from people reading posts, searching through post, etc. Therefore such optimization will never improve the bottleneck, and bottleneck is the only thing you worry about when it comes to DB :)

Offline CygnusX

  • Level 24
  • *
  • Posts: 303
  • Reputation: +3/-2
    • View Profile
    • Lords of Midnight
Re: Preventing Double Post
« Reply #4 on: January 17, 2011, 12:15:06 PM »
@Zeggy - this is ingenius... but I just realized it loses the optimization I was trying to gain by directing users back to the same page they were on.

@Chris - I'm not sure how cutting my DB calls significantly doesn't improve the bottleneck?  Certainly players do more clicking and reading than they do form submission, but even then, I think this would save me at least 5% of my DB calls overall.  

Still learning something new every day.  Thanks.
« Last Edit: January 17, 2011, 12:19:24 PM by CygnusX »

Offline Harkins

  • Level 28
  • **
  • Posts: 424
  • Reputation: +11/-2
  • Coder, blogger, entrepreneur.
    • View Profile
    • Push CX - Blog
Re: Preventing Double Post
« Reply #5 on: January 17, 2011, 05:10:56 PM »
Zeggy's right. (And this is standard Rails practice, too.)

Just redirect to whatever that page they submitted from (but don't use the http referer to do this, it's unreliable).

Visit #bbg on irc.freenode.net to talk browser games anytime.

Offline CygnusX

  • Level 24
  • *
  • Posts: 303
  • Reputation: +3/-2
    • View Profile
    • Lords of Midnight
Re: Preventing Double Post
« Reply #6 on: January 18, 2011, 11:23:10 AM »
The more I research this, the more it seems redirection is the only viable option.

So, 2 questions:

1) Is <?php header(); ?> the preferred redirection method, or <meta http-equiv="refresh">?  Currently, I'm assuming they're equal, though I prefer the latter.

2) Also, while I have many years of experience writing mysql queries... I have no experience with 'large' mysql tables.  And though I'm not expecting a 1M user base, I'd like to think I'm writing code that could handle this, but don't have any feeling for it.  So, in a theoretical game with 1M active users, if I'm constantly querying a table with ~25 columns (matching to UserID (int), indexed, limit 0,1.. which contains int and varchar fields, no text fields), should I expect bottleneck difficulties, or should I be ok?

Thanks in advance.  You guys are great : )
 
« Last Edit: January 18, 2011, 11:24:59 AM by CygnusX »

Offline Barrikor

  • Level 21
  • *
  • Posts: 248
  • Reputation: +3/-0
    • View Profile
Re: Preventing Double Post
« Reply #7 on: January 18, 2011, 01:16:00 PM »
I prefer <?php header(); ?>

The <meta http-equiv="refresh"> is client-side of course, I think the refresh can be noticeable sometimes.
Projects: Pith Framework (at 0.5), CactusGUI (at 0.3)

Offline CygnusX

  • Level 24
  • *
  • Posts: 303
  • Reputation: +3/-2
    • View Profile
    • Lords of Midnight
Re: Preventing Double Post
« Reply #8 on: January 18, 2011, 01:49:23 PM »
It is noticable...  but I have had trouble in the past getting header() to work properly.  I've had several 'headers have already been passed' type errors.  Seems like it had something to do with session_start();.  Or, perhaps it had something to do with me being an amateur programmer   :D  Either way, I am not experienced with the function, which is why I'm asking.



Offline Nox

  • Level 35
  • **
  • Posts: 767
  • Reputation: +12/-2
    • View Profile
Re: Preventing Double Post
« Reply #9 on: January 18, 2011, 02:02:23 PM »
Headers already passed means you had some output - any output - before a function that manipulates with headers (header, session start, setcookie...). That can be any output, even a white-space or DOM. So it's better not to output anything until the very end of the script run
Meet us at an IRC irc.freenode.net #bbg as well
https://vimeo.com/36579366 (a must-watch) | Join BOINC - no longer a hype, but you can help never the less

Offline Harkins

  • Level 28
  • **
  • Posts: 424
  • Reputation: +11/-2
  • Coder, blogger, entrepreneur.
    • View Profile
    • Push CX - Blog
Re: Preventing Double Post
« Reply #10 on: January 18, 2011, 05:25:57 PM »
If you use header(), you can redirect without sending any page at all. If you use the meta tag, you have to send a document. Less bytes = more awesome.

Visit #bbg on irc.freenode.net to talk browser games anytime.

Offline CygnusX

  • Level 24
  • *
  • Posts: 303
  • Reputation: +3/-2
    • View Profile
    • Lords of Midnight
Re: Preventing Double Post
« Reply #11 on: January 18, 2011, 08:53:33 PM »
header() is the better method....

my problem is, i think my server starts trying to send header information on any page call.  So, in times past, header() has always thrown the 'headers already sent' error.  Even after spending hours searching for whitespace, i came up empty.  This is why I abandoned the method.

But, by doing.

<?php
ob_start();

...php code...

header("Location: somepage.php"); //Redirect
ob_end_flush();

?>

I can buffer all the output from being sent until I call header();.  Works beautifully, and solves a long standing problem I've had.

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: Preventing Double Post
« Reply #12 on: January 19, 2011, 04:35:52 AM »
I'm not sure how cutting my DB calls significantly doesn't improve the bottleneck?  Certainly players do more clicking and reading than they do form submission, but even then, I think this would save me at least 5% of my DB calls overall.  
1) I don't think you will get 5% posts, reads would be more frequent I think... but assume you do.
2) These 5% of querries do not make 5% of performance. Post is just insert or update, no filesearch via complex non indexed criterias, no joins. These 5% querries would make more like 0.5% of performance... But assume it does not.
3) If you make the DB faster by 5-20% does it change anything? Does it make it crash less? No, it does not. Optimization is when you improve the performance by 100%, 200%, 300%. Then it might make sense. Petty improvements of 20-30% is just a thing you do when you are bored, not when your server has problems.

Quote
So, in a theoretical game with 1M active users, if I'm constantly querying a table
... This is beyond "lol"... When you have 1M daily users you have your own database already written by the best coders on the planet. You don't code your game anymore, you have no time for this since all the time is eaten up by the high level administration duties and public relation you can not delegate to lower ranks. At this scale you don't care about optimization anymore, you have a separate department of coders that do it for you. Also, I think 10k daily users is a physical limit for single server architecture nowadays, assuming you have ultimate optimization, very simple gameplay and top hardware.

Offline CygnusX

  • Level 24
  • *
  • Posts: 303
  • Reputation: +3/-2
    • View Profile
    • Lords of Midnight
Re: Preventing Double Post
« Reply #13 on: January 19, 2011, 07:36:08 AM »
@Chris - thanks for the feedback.  I'm still really uneasy about how well MySql/PhP scales for a novice programmer...

Also, I did my own quick analysis of a 1M user table that had a UserID (int) indexed... and realized that there should only be roughly 19 iterations of search required to sort through a b-tree of 1M rows.  This is miles better than a sorted, linear search of 1M users, so it made me feel a lot better.  Not sure if this is how it would work in reality or not, but it sounded good to me : )

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: Preventing Double Post
« Reply #14 on: January 19, 2011, 08:34:09 AM »
Number of total users on the table is almost irrelevant, SQL can handle quite big numbers. It's daily active users that drain resources. I used to run a game on $0.99/month shared host :D There were 10,000 accounts total (not in a hidden table, but processed, some on each page refresh), still the only problem was when 100-200 active users were trying to access the game during round start.

I would say: 1,000 daily users per world/server if your game is complex, 3,000 if the code is optimized and gameplay not heavy, 5,000 would be near the reasonable limit, 10,000 would be the absolute top humanly possible. After that you go either multiserver or split to multiworlds.

Offline CygnusX

  • Level 24
  • *
  • Posts: 303
  • Reputation: +3/-2
    • View Profile
    • Lords of Midnight
Re: Preventing Double Post
« Reply #15 on: January 19, 2011, 08:39:14 AM »
How do you suppose facebook does it?  Ie, in its multi-server setup, do you have servers that handle incomming connections, and another server to handle DB queries?  I know of large server farms, I'm just not sure how the internals work on these.  Just curious.
« Last Edit: January 19, 2011, 08:43:07 AM by CygnusX »

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: Preventing Double Post
« Reply #16 on: January 19, 2011, 08:42:53 AM »
How do you suppose facebook does it?
Facebook is not a game. And not made by a lone programmer :D They have, so called, "funds" :)

They have multiserver architecture.
Take a note that WoW does not have multiserver architecture.

Offline Zeggy

  • Global Moderator
  • Level 35
  • *****
  • Posts: 1,187
  • Reputation: +13/-4
    • View Profile
Re: Preventing Double Post
« Reply #17 on: January 19, 2011, 10:00:10 AM »
Facebook has 50,000+ servers :P

Chris: What do you mean, WoW does not have a multiserver architecture?

Offline Harkins

  • Level 28
  • **
  • Posts: 424
  • Reputation: +11/-2
  • Coder, blogger, entrepreneur.
    • View Profile
    • Push CX - Blog
Re: Preventing Double Post
« Reply #18 on: January 19, 2011, 10:21:12 AM »
How do you suppose facebook does it?  Ie, in its multi-server setup, do you have servers that handle incomming connections, and another server to handle DB queries?  I know of large server farms, I'm just not sure how the internals work on these.  Just curious.

http://highscalability.com has some great info on big setups, including some company profiles. I can't remember if I've seen a profile of Facebook on there in the last few years.

Visit #bbg on irc.freenode.net to talk browser games anytime.

Offline Zeggy

  • Global Moderator
  • Level 35
  • *****
  • Posts: 1,187
  • Reputation: +13/-4
    • View Profile
Re: Preventing Double Post
« Reply #19 on: January 19, 2011, 10:48:28 AM »

Offline Chris

  • Game Owner
  • Level 35
  • *
  • Posts: 2,217
  • Reputation: +28/-1
    • View Profile
Re: Preventing Double Post
« Reply #20 on: January 19, 2011, 10:58:21 AM »
Chris: What do you mean, WoW does not have a multiserver architecture?
I mean that they have separate worlds and players play in these worlds separately. Like you can not play with Chinese player next to you if you are on North US server let's say.

Offline codestryke

  • Administrator
  • Level 33
  • *****
  • Posts: 589
  • Reputation: +22/-0
    • View Profile
    • eXtremeCast Games
Re: Preventing Double Post
« Reply #21 on: January 19, 2011, 12:12:14 PM »
<?php
ob_start();

...php code...

header("Location: somepage.php"); //Redirect
ob_end_flush();

?>
Be aware though that any code after the redirect/ob_end_flush *IS* going to get executed. A redirect does not stop the rest of the page from getting executed. This is why you are getting the errors you are now and the call to ob_end_flush() is just masking the error. The call to header() should always be followed by a call to exit to let the interpreter know to stop processing the code on that page.

Knowing performance is great and it really does help the longevity of your game, however, the reality of it is when you start getting enough players you will get the funds (like Chris said). At that point you call XYZ hosting and tell them what you have, what you are running and they will setup your server farm for  you. They are the experts, you can't be an expert in everything and if you try you will be stuck at the hobbyist level when it comes to running a game.




Creating online addictions, one game at a time:

 


SimplePortal 2.3.3 © 2008-2010, SimplePortal