Announcement

Collapse
No announcement yet.

MultiThreaded FastCGI App Server

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

  • MultiThreaded FastCGI App Server

    Hello everyone.

    I am writing a little multithreaded FastCGI server, which i would like to describe
    briefly, and get your constructive criticism.

    Creates a modeless dialog with 2 buttons, OK(go) button, Stop button.
    Then hides and shows an icon in the taskbar.

    Creates a fixed number(configurable) of worker threads in Suspended state.
    A FastCGI server should not be running on a single thread.

    Creates a circular Queue. This is an array of requests(FCGX_Request)
    coming from WebServer, with 2 pointers. One points to next available
    slot, the other to next unprocessed slot(Request). The size of this
    array is 5 slots(default) times number of worker threads.

    Program sets Above-Normal priority to main thread. This thread is in a
    PeekMessage loop, waiting for messages like user input(Stop/Go) events,
    or Suspend inactive thread commands. If no message pending, sleeps for
    (number of threads * 25) milliseconds.

    Creates an Accept Request Thread(Dispatcher), also at Above-Normal priority.
    This thread is in a loop waiting for requests(FCGX_Accept_r). When a
    new request is received, if a thread is available(Suspended) it Resumes
    that thread to handle this request. If all threads are busy it just lets
    the new request in the circular queue. This allows to accept more requests
    than worker threads.

    When a worker thread is ready(Resumed) to handle a request, it calls Handlerequest
    procedure in HandlReq.dll, passing that procedure a pointer to FCGX_Request.
    This procedure must be ThreadSafe. In this Handlreq.dll all HTML output
    should be created and sent to WebServer. This separates the FastCGI server
    from the application DLL.

    When a worker thread finishes handling a request, it looks in the queue
    for another request(Synch by Mutex), if none available it goes back to
    Suspended state by sending message to main thread to suspend itself.

    I am testing this server with the Abyss WebServer, but under very light load.
    Anything wrong with the overall design, performance, or any other issue?
    I thank you very much for your comments, and opinions. I know there are many
    competent programmers in this forum.

    Thank you

  • #2
    I think one of the main issues in this FastCGI server is the
    technique of suspending, resuming the worker threads. The worker
    threads are always kept in a loop, calling on any type of(ThreadSafe) App DLL.
    Code:
    DECLARE FUNCTION HandleRequest LIB "HANDLREQ.DLL" (req AS FCGX_Request) AS LONG
    '***************************************************************
    FUNCTION thread_run(BYVAL i AS LONG) AS LONG
    '***************************************************************
    LOCAL e AS LONG, ix AS LONG
            DO
               IF threads(i, 1)=-1 THEN EXIT DO
               ix=cq_dequeue()                      'Look into Circular Queue
               IF ix>0 THEN                         'FCGI_Request Available
                    e=HandleRequest(cq(ix))         'Call ANY Application DLL
               ELSE
                    IF quitflag THEN
                            threads(i, 1)=-1
                            check_running
                            EXIT DO
                    END IF
                    SendMessage hDlg, %THREAD_SUSPEND, 0, i   'To MAIN thread
               END IF
            LOOP
            thread_run=-1
    END FUNCTION
    '***************************************************************
    'DOEVENTS - MAIN THREAD
    CALLBACK FUNCTION xDialog()
    '***************************************************************
            CASE %THREAD_SUSPEND
                    i=CBLPARAM
                    THREAD SUSPEND threads(i, 0) TO x
                    threads(i, 1)=0
    END FUNCTION
    Not sure if this is the most efficient performance wise.

    Another issue is keeping more requests than available threads.
    No need for excessive number of threads. This could be a key point.
    Code:
    '***************************************************************
    SUB get_thread()        'Called by Acceptreq Thread
    '***************************************************************
    LOCAL i AS LONG, x AS LONG
        FOR i=1 TO nthreads
            IF threads(i, 1)=0 THEN EXIT FOR  'Thread available
        NEXT i
        IF i>nthreads THEN                    'All worker threads Busy
            i=0                               'Keep FCGX_Request in Circular Queue
        ELSE
            threads(i, 1)=1
            THREAD RESUME threads(i, 0) TO x  'Wake first available thread
        END IF
    END SUB
    I appreciate very much your commnents on this work.

    Comment


    • #3
      Sample?

      I am kind of confused on how FastCGI works. I have downloaded DLL the samples from http://www.coastrd.com/.

      I compile the samples and then try to run them and all I get is ERROR 500.

      Using the latest Abyss Web Server I added the virtual path /cgi-bin/*.exe to the Scripting Parameters and made it Fast CGI (Local - Pipes).

      I get this error in my Fast CGI log:
      Writing 5392 bytes failed = The process cannot access the file because it is being used by another process.
      Thank you,
      Ryan M. Cross

      Comment


      • #4
        Hello

        Now i realize there is no need for the modeless window and the PeekMessage loop.

        I was confused with the fact that the Main Thread is running in Above-Normal priority.

        So now the window is modal, and there is no PeekMessage loop. When the
        user press the Stop button a FCGC_Shutdownpending is executed and a
        Dialog End breaks the modal window.

        After that, the main thread resumes worker threads that are Suspended,
        so they break out of their loop, and exit.

        Bye

        Comment

        Working...
        X