Live data from Hacker News

Stack Overflow Outage Postmortem

stackstatus.net

301–310 of 335 posts

Re: Stack Overflow Outage Postmortem

#301
post #182

As perlfaq4[1] shows: > You can do that with a pair of substitutions: > s/^\s+//; > s/\s+$//; It then notes, in an understated manner: > You can also write that as a single substitution, > although it turns out the combined statement is > slower than the separate ones. That might not > matter to you, though: > s/^\s+|\s+$//g; [1]: http://perldoc.perl.org/perlfaq4.html#How-do-I-strip-blank-s...

In light of the given issue, it might be a good idea to update the example code to use \s++ instead...

Re: Stack Overflow Outage Postmortem

#302
post #70

> If the string to be matched against contains 20,000 space characters in a row, but not at the end, then the Regex engine will start at the first space, check that it belongs to the \s character class, move to the second space, make the same check, etc. After the 20,000th space, there is a different character, but the Regex engine expected a space or the end of the string. Realizing it cannot match like this it back…

Perl does a pretty good job at optimizing such things:

    $ time perl -Mre=debug -e '(" " x 100000000 . "X") =~ /\s+$/ && print "MATCH"'
    Compiling REx "\s+$"
    Final program:
       1: PLUS (3)
       2:   POSIXD[\s] (0)
       3: EOL (4)
       4: END (0)
    floating ""$ at 1..9223372036854775807 (checking floating) stclass POSIXD[\s] plus minlen 1 
    Matching REx "\s+$" against "                                                            "...
    Intuit: trying to determine minimum start position...
      Found floating substr ""$ at offset 100000001...
      (multiline anchor test skipped)
      looking for class: start_shift: 1 check_at: 100000001 rx_origin: 0 endpos: 100000001
      Does not contradict STCLASS...
    Intuit: Successfully guessed: match at offset 0
    Matching stclass POSIXD[\s] against "                                                            "... (100000001 bytes)
       0           |  1:PLUS(3)
                                      POSIXD[\s] can match 100000000 times out of 2147483647...
    100000000         |  3:  EOL(4)
                                        failed...
                                      failed...
    Contradicts stclass... [regexec_flags]
    Match failed
    Freeing REx: "\s+$"
    
    real    0m0.427s
    user    0m0.312s
    sys     0m0.076s
Basically, the regex egine sees a $ anchor, moves to the end of the string, and finds that it can't ever match there.

It makes it quite hard to accidentally trigger such bad regex behavior. See for example https://perlgeek.de/blog-en/perl-tips/in-search-of-an-expone... (disclaimer: my own blog)

Re: Stack Overflow Outage Postmortem

#303

Earlier quoted context omitted.

There's a simple trick the real-time and high-assurance communities use to catch stuff like this: enforce a hard limit for time each task takes to complete. Some you might give leeway to prevent DDOS'ing your users. Many (most?) things have a sane, hard limit that can apply along with a log entry or notification to ops. Keeps one user or task from DDOSing whole system or forces it to fail fast + noticeably. Note a lo…

You can only safely abort a "task" if the task has specifically be designed that way, or if the task is a process.

Which is of course part of his point. Anything that processes arbitrary user input should be designed in a way that is abortable in some way. As this particular case shows even the attempts to sanitize input can be vectors for a DOS against them.

Re: Stack Overflow Outage Postmortem

#304
post #152

Earlier quoted context omitted.

I've fixed so many bugs using regex, only to have to fix several bugs later. My current stance is, avoid regex if at all possible. Turns out, many of the things we use regex for is possible without. Often times, .Substring, .IndexOf, and using LINQ over strings is sufficient.

Regexes are almost always a massive code smell. They should almost never be used, bad idea, bad implementation, hard to grok, hard to debug, hard to test, hard to spot. Whoever came up with them has surely been given the same honorary place in hell with Jon Postel, who invented the utterly disastrous "be liberal in what you accept", that has plagued all web developers for the last 20 years.

This is a load of BS. They are quite capable (and fast) tools in the right hands. And they are easily (and SHOULD be) tested, in any test suite.

As proof, I submit some email header parsing code which I rewrote as a well-commented Regex which was something like 300x faster than using the Mail gem: https://github.com/pmarreck/ruby-snippets/blob/master/header...

Once you know what to look for re: catastrophic backtracking, you know how to avoid it. This is called programmer skill.

Re: Stack Overflow Outage Postmortem

#305
post #261

Earlier quoted context omitted.

i wish people would stop using regular expressions in situations where they can be replaced with a substring function.

Nick explained on Reddit why the regex was used[1]: > While I can't speak for the original motivation from many moons ago, .Trim() still doesn't trim \u200c. It's useful in most cases, but not the complete strip we need here. This would have probably been my train of thought (assuming that I consider regex to be a valid solution): Trim() would have been the correct solution, were it not for that behavior. Substring i…

Oh totally. I assumed that unicode bs immediately. And anyone would make this mistake easily. That's the point -- gotta have it imprinted in the brains, that regexes are for finding things in files, not for your production code. I've used them myself, but I'd like to think that when i type that regex in i stop and thing whether i will be feeding raw user inputs into it.

Re: Stack Overflow Outage Postmortem

#306

Earlier quoted context omitted.

But that's a weird character to put in a comment line! I don't get how this would happen accidentally.

Runaway automatic search-and-replace? There's no way to distinguish intent .

Runaway search and replace won't put a single 200 width whitespace character AFAICT

Re: Stack Overflow Outage Postmortem

#307
post #244

Earlier quoted context omitted.

Agreed that's impressive debugging for this issue. But... > 10 minutes to roll out the fix That seems very slow to me. 30% of their down time was because their deploy process is slow.

10 minutes roll out to production is insanely fast. Roll out usually goes through build, test, staging, and to farms of production servers, with smoke tests in each stage along the way.

Rollout to thousands of servers on WordPress.com is typically less than 60 seconds. We optimize for reverting fast.

Its just interesting to me the implications of what folks optimize for and that this is considered fast. We have very minimal deploy testing and optimize to be able to revert quickly when there are problems because performance issues like this are very hard to predict. Probably means we create many smaller short hiccups though (that generally are not a full site crash).

Re: Stack Overflow Outage Postmortem

#308
post #303

Earlier quoted context omitted.

You can only safely abort a "task" if the task has specifically be designed that way, or if the task is a process.

Which is of course part of his point. Anything that processes arbitrary user input should be designed in a way that is abortable in some way. As this particular case shows even the attempts to sanitize input can be vectors for a DOS against them.

It's why you use isolation techniques outside that code as the fall-back. Simplest forms I saw involved while loops counting downward and threads that got interrupted to assess things.

Re: Stack Overflow Outage Postmortem

#310
post #305

Earlier quoted context omitted.

Nick explained on Reddit why the regex was used[1]: > While I can't speak for the original motivation from many moons ago, .Trim() still doesn't trim \u200c. It's useful in most cases, but not the complete strip we need here. This would have probably been my train of thought (assuming that I consider regex to be a valid solution): Trim() would have been the correct solution, were it not for that behavior. Substring i…

Oh totally. I assumed that unicode bs immediately. And anyone would make this mistake easily. That's the point -- gotta have it imprinted in the brains, that regexes are for finding things in files, not for your production code. I've used them myself, but I'd like to think that when i type that regex in i stop and thing whether i will be feeding raw user inputs into it.

Many times regexes are more clear and therefore less bug prone than any non regex alternative. They have their use. Even in production.
Post reply on HN