how to have wait-for alternative on appserver?

Posted by Jurjen Dijkstra on 03-Aug-2010 07:49

Hallo,

I have a ABL programming problem.

There is a requirement that the appserver uses a socket to download a file from a webserver. So the socket sends an HTTP POST request and after some little while it receives the requested data from the webserver, in multiple chunks. Not difficult when the code runs on the client in a window or dialog, because in that case there is a WAIT-FOR that allows the socket to wait for incoming data and respond to it.

WAIT-FOR does not work on the appserver. So as an alternative I have tried to execute a loop with a PROCESS EVENTS statement inside, and continue to loop until all data is received (or until the socket disconnects, or until a timeout occurs).

It works, but is works bad. Slow. CPU at 100% and it takes much much more time to download the data then from a window.

It makes perfect sense that PROCESS EVENTS is a loop does behave like it does. There needs to be a sleep or wait or something in the loop as well, but how?

Do any of you have a good WAIT-FOR like algorithm for appserver, to wait for data on a socket? We have OE 10.2B.

Thanks,

Jurjen.

All Replies

Posted by jankeir on 03-Aug-2010 07:56

Maybe you can sleep a few miliseconds?

win api: http://www.oehive.org/node/511

It can be done with a unix shared object and  an external procedure as well, but I can't find that code.

Posted by jankeir on 03-Aug-2010 08:04

Unix: http://www.dbappraise.com/ppt/shlib.pptx Look for shortsleep.

Posted by Peter Judge on 03-Aug-2010 08:20

Can't you use WAIT-FOR "U1" or something similar?

I think the below is true for AppSErver clients as well as batch-mode clients.

-- peter

Posted by maximmonin on 03-Aug-2010 09:30

I used the following method:

backgrond process:

CREATE SERVER-SOCKET hServer.

lRC = hServer:SET-CONNECT-PROCEDURE('ProcessClientConnect') NO-ERROR.

....

REPEAT ON STOP UNDO, LEAVE ON QUIT UNDO, LEAVE:

    WAIT-FOR CONNECT OF hServer PAUSE 1.

    for each procs:

      phandle = WIDGET-HANDLE(procs.phandle).

      if not VALID-HANDLE(phandle) then

      do:

        delete procs.

        NEXT.

      end.

      APPLY "GO" TO phandle.

    end.

END.

PROCEDURE ProcessClientConnect:
    DEFINE INPUT PARAMETER hSocket AS HANDLE NO-UNDO.
    define variable phand as HANDLE.
    define variable qid as character.
    define variable disp-val as integer.
    hSocket:SET-SOCKET-OPTION("TCP-NODELAY", "TRUE" ).
    run appserv/connected.p PERSISTENT SET phand (hSocket, RecoverTimeout).
    create procs.
    procs.phandle = STRING(phand).
    APPLY "GO" to phand.
....
END PROCEDURE.
connected.p:
....
ON GO OF THIS-PROCEDURE
DO:
....
    repeat:
        l = hSocket:GET-BYTES-AVAILABLE().
        if l = 0 then leave.
        if l > 0
        then do:
          run socket_ReadLine(hSocket, OUTPUT str).
.....
     end.
END.

Posted by Jurjen Dijkstra on 03-Aug-2010 10:18

Thanks, but I am afraid this algorithm has a problem too.

hSocket:get-bytes-available() is not a blocking statement, so the loop iterates tens thousands of times even for a small download. That means it is hitting hard on the CPU, decreasing overall performance.

I think I have found a solution in the meantime:

It's still a loop but now around the hSocket:READ  statement, decorated with some timeout checks. hSockect:READ is a blocking statement that waits until enough bytes arrived, so it does not cost a lot of CPU (assuming thet the internals of the READ statement are efficient).

The end-result is in the attachment at topic   http://communities.progress.com/pcom/message/82703

Thanks!

Jurjen.

This thread is closed