Webserver fail



  • I present you this awesome code. For those not familiar with ASP.NET, these are pretty much the first/last things that happen when serving a web request.

    (Formating is preserved from original source)

    	protected virtual void Application_BeginRequest (Object sender, EventArgs e)
    		{
                // One Request in time 
                int i = 0;
                while (request)
                {
                    Thread.Sleep(100);
                    i++;
    
                if (i > 10)
                    break;
            } 
    
            request = true;
    	}
    	
    	protected virtual void Application_EndRequest (Object sender, EventArgs e)
    	{
            request = false;
    	}
    

    Im still not sure why was there, maybe a version of the speed up loop?



  •  Rarely does code make me want to punch someone in the face.

     



  • That looks like the world's worst attempt at writing a mutex.



  • @SandGroper said:

    I present you this awesome code. For those not familiar with ASP.NET, these are pretty much the first/last things that happen when serving a web request.

    (Formating is preserved from original source)

    	protected virtual void Application_BeginRequest (Object sender, EventArgs e)
    {
    // One Request in time
    int i = 0;
    while (request)
    {
    Thread.Sleep(100);
    i++;

                if (i > 10)
                    break;
            } 
    
            request = true;
    	}
    	
    	protected virtual void Application_EndRequest (Object sender, EventArgs e)
    	{
            request = false;
    	}
    

    Im still not sure why was there, maybe a version of the speed up loop?

    Am I understanding this correctly: the person wanted to make sure only one request was started per second, but is doing so from within the request, in code that is not part of the actual web server? Meaning it's like trying to make paint dry quicker by spreading it more slowly, except he's actually not spreading it more slowly?



  • @SandGroper said:

                int i = 0;
    	    while (request)
                {
                    Thread.Sleep(100);
                    i++;
    
                if (i > 10)
                    break;
            }</pre></blockquote> But why the complicated wait? A much simpler waiting loop would have sufficed.
    
     	    while (request)
                {
                    Thread.Sleep(100);
                }

    I only hope the request variable was defined as volatile, or else the wait would be forever. At least in Java. Don't know how C# would handle this.

    But, yeah, I find it fascinating how a multi-user system is serialized to a crawl. Gives me ideas.



  • @TheRider said:

    @SandGroper said:

                int i = 0;
    while (request)
    {
    Thread.Sleep(100);
    i++;

                if (i &gt; 10)
                    break;
            }</pre></blockquote> But why the complicated wait? A much simpler waiting loop would have sufficed.
    
     	    while (request)
                {
                    Thread.Sleep(100);
                }

    But then you won't break out automatically after a second if the "mutex" hasn't released yet.

    @TheRider said:

    I only hope the request variable was defined as volatile, or else the wait would be forever. At least in Java. Don't know how C# would handle this.

    I suspect that even in Java, a class level variable is assumed to be able to change from other threads.

    Of course, now that we're on the subject, this is the world's worst non-mutex, since it doesn't even try to prevent multiple execution, since it gives up after 1 second.



  •  In addition to the obvious WTFs, on a multi processor machine the request variable wiil be cached in each processor and. well, another reason it won't work.



  • @pkmnfrk said:

    I suspect that even in Java, a class level variable is assumed to be able to change from other threads.

    Not if it's not declared volatile..



  • @verisimilidude said:

     In addition to the obvious WTFs, on a multi processor machine the request variable wiil be cached in each processor and. well, another reason it won't work.

    Last time I checked, ASP.NET is only running under Windows server, and Windows server can only run on a machine with implicit cache coherency.


  • @TheRider said:

    But why the complicated wait?
    Because then you wouldn't have a non-blocking WTF, duh...

    Seriously, one wonders what the rest of the code would look like. Just think of the unnecessary race conditions, global static variables, swallowed exceptions, and other such goodies that lurk within that "code base"...



  • @pkmnfrk said:

    But then you won't break out automatically after a second if the "mutex" hasn't released yet.
    Oh! I didn't realize that. Thanks for filling me in.

    Come to think of it, users must really enjoy the fact that web requests never take longer than one second. Or that they start to fail in strange ways if they take longer than that.



  • What kind of thinking could possibly come up with this? If two requests can run concurrently, then this code is unnecessary. If they cannot, then this code is insufficient. The motivation is more perplexing than the implementation.



  • I reckon they were using the request time as a key, but only accurate to the nearest second.

    Oh no, my keys are non-unique! What to do...?

    shudder



  • @aihtdikh said:

    I reckon they were using the request time as a key, but only accurate to the nearest second.

    Oh no, my keys are non-unique! What to do...?

    shudder

    I don't think it would do that. It doesn't limit it to one request per-second, it kinda-sorta prevents concurrent requests, but it could still have many requests per-second.



  • @alegr said:

    Last time I checked, ASP.NET is only running under Windows server, and Windows server can only run on a machine with implicit cache coherency.
    A client of mine has been running an ASP.net site on Linux/Apache/Mono for years...



  • @ender said:

    @alegr said:
    Last time I checked, ASP.NET is only running under Windows server, and Windows server can only run on a machine with implicit cache coherency.
    A client of mine has been running an ASP.net site on Linux/Apache/Mono for years...

    I'm 99.99% sure that was an x86 or x64 machine. Implicit cache coherency.


  • @alegr said:

    @ender said:

    @alegr said:
    Last time I checked, ASP.NET is only running under Windows server, and Windows server can only run on a machine with implicit cache coherency.
    A client of mine has been running an ASP.net site on Linux/Apache/Mono for years...

    I'm 99.99% sure that was an x86 or x64 machine. Implicit cache coherency.

    Here, let me fix his quote for you.

     

    @ender said:

    @alegr said:
    Last time I checked, ASP.NET is only running under Windows server
    A client of mine has been running an ASP.net site on Linux/Apache/Mono for years...



  • @morbiuswilters said:

    @aihtdikh said:
    I reckon they were using the request time as a key, but only accurate to the nearest second.

    Oh no, my keys are non-unique! What to do...?

    shudder

    I don't think it would do that. It doesn't limit it to one request per-second, it kinda-sorta prevents concurrent requests, but it could still have many requests per-second.


    You're quite right - I should have said 'as a temporary key in a hash table of currently-active requests'.

    Oh and congratulations on the upcoming 7000-post milestone.



  • @Sutherlands said:

    @alegr said:

    @ender said:

    @alegr said:
    Last time I checked, ASP.NET is only running under Windows server, and Windows server can only run on a machine with implicit cache coherency.
    A client of mine has been running an ASP.net site on Linux/Apache/Mono for years...

    I'm 99.99% sure that was an x86 or x64 machine. Implicit cache coherency.

    Here, let me fix his quote for you.

     

    @ender said:

    @alegr said:
    Last time I checked, ASP.NET is only running under Windows server
    A client of mine has been running an ASP.net site on Linux/Apache/Mono for years...

    I'm afraid everybody forgot that I was refuting a claim of a danger of a variable being cached on one processor. I was making a point that ASP.NET will (99.99% likely) run on a machine with implicit cache coherency (IA32 which includes x86 and x64).


  • I propose a new indentation style.

    @SandGroper said:


    {
    request = false;
    }

    The two-handed sword of source code!



  • @TheRider said:

    @SandGroper said:

                int i = 0;
    while (request)
    {
    Thread.Sleep(100);
    i++;

                if (i &gt; 10)
                    break;
            }</pre></blockquote> But why the complicated wait? A much simpler waiting loop would have sufficed.
    
     	    while (request)
                {
                    Thread.Sleep(100);
                }

    I only hope the request variable was defined as volatile, or else the wait would be forever. At least in Java. Don't know how C# would handle this.

    But, yeah, I find it fascinating how a multi-user system is serialized to a crawl. Gives me ideas.

    The "10" threshold may be a way to break down the wait time and cause multiple context switching while waiting for a specific time. Something like that could be used to keep the application warm and avoid JIT compilation delays for real requests.



  • @Speakerphone Dude said:

    @TheRider said:

    @SandGroper said:

                int i = 0;
    while (request)
    {
    Thread.Sleep(100);
    i++;

                if (i &gt; 10)
                    break;
            }</pre></blockquote> But why the complicated wait? A much simpler waiting loop would have sufficed.
    
     	    while (request)
                {
                    Thread.Sleep(100);
                }

    I only hope the request variable was defined as volatile, or else the wait would be forever. At least in Java. Don't know how C# would handle this.

    But, yeah, I find it fascinating how a multi-user system is serialized to a crawl. Gives me ideas.

    The "10" threshold may be a way to break down the wait time and cause multiple context switching while waiting for a specific time. Something like that could be used to keep the application warm and avoid JIT compilation delays for real requests.

    No. Stop trying to rationalize this. What's more, I don't even think what you said made any sense. It's not keeping the application warm (besides, how is forcing every waiting thread to do excessive context switching going to do that?)



  • @morbiuswilters said:

    @Speakerphone Dude said:
    @TheRider said:

    @SandGroper said:

                int i = 0;
    while (request)
    {
    Thread.Sleep(100);
    i++;

                if (i &gt; 10)
                    break;
            }</pre></blockquote> But why the complicated wait? A much simpler waiting loop would have sufficed.
    
     	    while (request)
                {
                    Thread.Sleep(100);
                }

    I only hope the request variable was defined as volatile, or else the wait would be forever. At least in Java. Don't know how C# would handle this.

    But, yeah, I find it fascinating how a multi-user system is serialized to a crawl. Gives me ideas.

    The "10" threshold may be a way to break down the wait time and cause multiple context switching while waiting for a specific time. Something like that could be used to keep the application warm and avoid JIT compilation delays for real requests.

    No. Stop trying to rationalize this. What's more, I don't even think what you said made any sense. It's not keeping the application warm (besides, how is forcing every waiting thread to do excessive context switching going to do that?)

    Context-switching is an easy way to generate activity in the performance counters in Windows without impacting I/O (the real costly resource). If someone wants a quick, dirty and economical solution to fake activity from within a worker process, looping inThread.Sleep(100) should work; it could fool a resource monitoring utility into thinking that the service is not idle, something that would be less likely to be achieved with a single wait.

    This being said, I share your opinion that the actual explanation in this situation is probably less interesting.


  • :belt_onion:

    @Speakerphone Dude said:


    Context-switching is an easy way to generate activity in the performance counters in Windows without impacting I/O (the real costly resource). If someone wants a quick, dirty and economical solution to fake activity from within a worker process, looping inThread.Sleep(100) should work; it could fool a resource monitoring utility into thinking that the service is not idle, something that would be less likely to be achieved with a single wait.

    I actually understood what you said the first time, but when I realized (after this follow-up) that you weren't trolling, I died a little on the inside.



  • @Speakerphone Dude said:

    Context-switching is an easy way to generate activity in the performance counters in Windows without impacting I/O (the real costly resource). If someone wants a quick, dirty and economical solution to fake activity from within a worker process, looping inThread.Sleep(100) should work; it could fool a resource monitoring utility into thinking that the service is not idle, something that would be less likely to be achieved with a single wait.

    What? Why would you want to do this?? Besides which, that's not what's happening here. The sleep is just so the thread doesn't consume CPU in between checking to see if The Request has finished. It's a very half-assed, race-prone mutex.



  • @Speakerphone Dude said:

    @TheRider said:

    @SandGroper said:

                int i = 0;
    while (request)
    {
    Thread.Sleep(100);
    i++;

                if (i &gt; 10)
                    break;
            }</pre></blockquote> But why the complicated wait? A much simpler waiting loop would have sufficed.
    
     	    while (request)
                {
                    Thread.Sleep(100);
                }

    I only hope the request variable was defined as volatile, or else the wait would be forever. At least in Java. Don't know how C# would handle this.

    But, yeah, I find it fascinating how a multi-user system is serialized to a crawl. Gives me ideas.

    The "10" threshold may be a way to break down the wait time and cause multiple context switching while waiting for a specific time. Something like that could be used to keep the application warm and avoid JIT compilation delays for real requests.

    It is true that if a process stays idle for too long, the operating system will kill it, unload it from memory, unregister it from IIS and delete it from the hard drive and any other network drives it can see because it's not doing anything important. That way it saves resources.


Log in to reply