Announcement

Collapse
No announcement yet.

Server Timeout Problem

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Server Timeout Problem

    Hello everyone

    Server shells(Createprocess) an application program the first
    time a request is received. Server is configured to TerminateProcess
    the application, if no new requests are received for, say 6 minutes.

    The problem is that the application program is unable to close the
    resources used, because of TerminateProcess.

    This is the case of a WebServer shelling a FastCGI app.

    If the application could detect inactivity for a period of 5 minutes,
    then it could close all resources, and shutdown. Thus preempting the server.
    Like a yellow light before a red traffic light.

    Is this a good approach?

    Thank you all.

  • #2
    > Server is configured to TerminateProcess
    > the application, if no new requests are received for, say 6 minutes.

    If this is your server, have that terminate itself, don't "terminate process" from either within or without.

    If it's not your server, don't "Terminate Process" from yourprogram.. see if you can find a "shutdown" or "exit" command. Or just let it run... it's a SERVER, right?

    As per SDK doc:
    The TerminateProcess function is used to unconditionally cause a process to exit. Use it only in extreme circumstances. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess.
    MCM
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      You need something in your program to know when there's been six minutes inactivity?

      Waitable Timer Object Demo June 2005

      MCM
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        See if size of logfile has changed every 5-minutes

        Code:
        #COMPILE EXE
        #DIM ALL
        #INCLUDE "win32api.inc"
        $Logfile = "C:\Abyss Web Server\log\access.log"
        FUNCTION PBMAIN () AS LONG
          LOCAL hThread AS DWORD
          THREAD CREATE CheckFileSize(5000) TO hThread   ' (5 minutes  = 300,0000 milliseconds
          THREAD CLOSE hThread TO hThread   
          SLEEP 50
         
          DO 'program loop
            IF THREADCOUNT = 1 THEN EXIT DO
            SLEEP 1000
          LOOP
          ? "Shutdown":SLEEP 1000
        END FUNCTION
        THREAD FUNCTION CheckFileSize(BYVAL milliseconds AS DWORD) AS LONG
          LOCAL StartSize AS QUAD
          DO
            StartSize = FileSize($LogFile)
            SLEEP milliseconds                       'specified wait
          LOOP UNTIL StartSize = FileSize($LogFile)  'no change, exit
        END FUNCTION
        FUNCTION FileSize(BYVAL sFileName AS STRING) AS QUAD
          'Bytes = FileSize(sFileName)  returns file size or -1 if any error
          LOCAL FindData AS WIN32_FIND_DATA
          LOCAL hDir AS LONG
          hDir = FindFirstFile(BYVAL STRPTR(sFileName), FindData)
          IF hDir = -1 THEN  'if not found return -1
            FUNCTION = -1
          ELSE               'return number of bytes
            FindClose hDir
            'Thank you, Pierre Bellisle
            FUNCTION = MAK(QUAD, FindData.nFileSizeLow , FindData.nFileSizeHigh)
          END IF
        END FUNCTION
        Last edited by Mike Doty; 25 Aug 2009, 04:50 PM. Reason: Added THREAD CLOSE and path to Abyss log
        CMD shortcut to open any location:
        %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
        Change to run as administrator
        How long is an idea? Write it down.

        Comment


        • #5
          It is not my Server. It is a WebServer(ABYSS) spawning a FastCGI app.

          I appreciate your responses, but I'm thinking of a simpler method.

          Code:
          Global Actflag As Long, Actcounter As Long
          Function accept_loop()
              DO
                  ret=FCGX_Accept_r(cq(n))
                  IF ret<0 THEN EXIT DO
                  Actflag=1                        'There is activity
                  ''''''''
                  '''''''
              LOOP
          End Function
           
          CALLBACK FUNCTION xDialog()
              SELECT CASE CBMSG
                  CASE WM_TIMER                'Every 1 minute
                          iF Actflag Then
                                  Actflag=0 : Actcounter=0
                                  Exit Function
                          Else
                              If Actcounter=5 then        '5 Minutes
                                  FCGX_ShutDownpending    'Preempt the Server TerminateProcess
                                  CloseAllResources
                                  QuitFlag=1
                                  Exit Function
                              Else
                                  INCR Actcounter
                              End If
                          End If
                  CASE ELSE
              END SELECT
          END FUNCTION
          I get to CloseAllResources before the 6 minutes Server Timeout.

          Is this right?

          Thanks again

          Comment


          • #6
            If it works, it's right.

            However, I wouldn't bother with all that counting minutes and looping and stuff.

            As long as you have a GUI (CODE NOT SHOWN)...
            On WM_CREATE/WM_INITDIALOG
            - Create six minute timer
            On WM_TIMER
            - you hit six minutes, do whatever
            On Activity
            - Kill the existing timer and create a new one to fire in six minutes.

            Looks simpler to me than all those DO loops and global and static variables.

            MCM
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              >>Looks simpler to me than all those DO loops and global and static variables.

              Suppose your timer starts and 2 minutes later there is a request(activity)
              then the timer ends, see activity and restarts again.

              Two minutes after the timer restarts the WebServer detects no activity for
              six minutes, and then TerminateProcess my FastCGI app.

              This is what we are trying to avoid.

              Am I right?

              Thanks

              Comment


              • #8
                I still like using the Abyss access.log.
                With a few more lines of code you can monitor all activity in real-time.
                CMD shortcut to open any location:
                %windir%\system32\cmd.exe /k " cd\ & x: & cd x:\xxxx
                Change to run as administrator
                How long is an idea? Write it down.

                Comment


                • #9
                  The problem is that the application program is unable to close the
                  resources used, because of TerminateProcess.
                  I 'assume' the code you show (post 5) is what you are running, the process which gets terminated via TerminateProcess() if the server detects no activity from it for six minutes.

                  Well, there are two obvious solutions:

                  1. Make sure there is some request - however innocuous - not less than every six minutes.
                  2. (the CORRECT fix) Don't allow your program to just sit there in a loop holding the resources. Get 'em, use 'em, release 'em before going back into an idle state.


                  MCM
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    I 'assume' the code you show (post 5) is what you are running, the process which gets
                    terminated via TerminateProcess() if the server detects no activity from it for six minutes.

                    2. (the CORRECT fix) Don't allow your program to just sit there in a loop holding the
                    resources. Get 'em, use 'em, release 'em before going back into an idle state.
                    Actually, the app does not make any request to the Webserver, it is BLOCKED
                    in the FCGx_Accept_r() function. It unblocks when the server sends a request
                    coming from a WebBrowser. Then it signals activity by setting the actflag to 1.

                    If the server does not receive any request from the WebBrowser for the app
                    in the timeout(6 min) period, it kills the app. The server has its own timeout procedure.


                    >>See if size of logfile has changed every 5-minutes

                    I think this has the same problem like the MCM timer procedure.
                    The solution here seems like we need a higher sampling rate(1 min). When we get 5 samples with no activity then we CloseAllResources, and quit.

                    Thank you again.

                    Comment


                    • #11
                      The solution here seems like we need a higher sampling rate(1 min). When we get 5 samples with no activity then we CloseAllResources
                      Where's the <expletive> smiley for "kludge" when you need it?
                      Michael Mattias
                      Tal Systems (retired)
                      Port Washington WI USA
                      [email protected]
                      http://www.talsystems.com

                      Comment


                      • #12
                        Excuse me for extending this topic.

                        But you see, someone offers a "solution" to this problem.
                        Read all about it here.

                        Talk about a kludge. I tried their solution, but could not get it to work.
                        I asked if anyone had any success with it. Seems like no one.

                        Then I decided to roll my own, and it works!
                        What could be simpler than this
                        Code:
                            SELECT CASE CBMSG
                                CASE %WM_TIMER   'Every one minute
                                        IF actflag THEN
                                                actflag=0 : actcount=0
                                        ELSE
                                            IF actcount = 4 THEN
                                                quitflag=-1 : FCGX_ShutdownPending
                                            ELSE
                                                INCR actcount
                                            END IF
                                        END IF
                        Is this a kludge?

                        Bye

                        Comment

                        Working...
                        X