Alaska Software Inc. - Socket Write Error Devil
Username: Password:
AuthorTopic: Socket Write Error Devil
Bruce AndersonSocket Write Error Devil
on Mon, 06 Sep 2004 14:06:14 -0500
I continue to have socket write errors.  I do not yet have the pattern to
predict them, but I believe it must be my code causing them.  I think the
problem is related to the oContext:openSession() calls.
Question: Can openSession() be called more than once in a Service Request?
Assuming an ongoing session and the first instance of openSession() gets the
cookie information, what do subsequent openSession() calls get?

I might have made my code too complicated.  I keep the current workspace and
recno() for each session in :getCargo().  In my program's logic flow, the
user-client submits a form, which contains several possible actions ("Save",
"Delete", "Show"), with the client's choice encoded as a hidden input.  The
WAA form-function receives the form data and passes oHtml and oContext onto
the appropriate internal function for the desired action.  Because of
session continuity testing, :openSession() :getCargo() can be called more
than once before I return a HTML page to the client.  I am wondering if this
coding and my socket write errors are related.

Curiousity:  What controls which available thread will be used to process a
Service Request?  In my simple test instance, I see thread assignments that
appear to be chosen randomly.
Phil Ide
Re: Socket Write Error Devil
on Tue, 07 Sep 2004 09:23:52 +0100
Bruce,

> I continue to have socket write errors.  I do not yet have the pattern to
> predict them, but I believe it must be my code causing them.  I think the
> problem is related to the oContext:openSession() calls.
> Question: Can openSession() be called more than once in a Service Request?
> Assuming an ongoing session and the first instance of openSession() gets the
> cookie information, what do subsequent openSession() calls get?

As far as I know, it should just return what is in the session (i.e. the
session array), and is non-destructive.  The easiest way to test this is to
open a session, add or change some of the data in it then open the session
again and see if any of the data has been lost.

> I might have made my code too complicated.  I keep the current workspace and
> recno() for each session in :getCargo().  In my program's logic flow, the
> user-client submits a form, which contains several possible actions ("Save",
> "Delete", "Show"), with the client's choice encoded as a hidden input.  The
> WAA form-function receives the form data and passes oHtml and oContext onto
> the appropriate internal function for the desired action.  Because of
> session continuity testing, :openSession() :getCargo() can be called more
> than once before I return a HTML page to the client.  I am wondering if this
> coding and my socket write errors are related.

Perhaps you could simply add a test to say whether the session has already
been opened?  Simply setting a thread-specific flag can do this for you.

> Curiousity:  What controls which available thread will be used to process a
> Service Request?  In my simple test instance, I see thread assignments that
> appear to be chosen randomly.

Threads are utilised in a ring. If you have 5 worker-threads, wt#1 is used
first, followed by wt#2 etc, with wt#1 following wt#5.

I use a simple mechanism to store thread-specific values (see comments
below):

Function Global(lKill)
   STATIC aGlob
   local nThread := ThreadID()
   local oRet
 
   DEFAULT lKill to FALSE

   if !lKill .and. aGlob == NIL
      aGlob := Array(nThread)
   endif
   if !lKill .and. Len(aGlob) < nThread
      ASize(aGlob, nThread)
   endif
   if lKill
      aGlob[nThread] := NIL
   else
      if aGlob[nThread] == NIL
         aGlob[nThread] := MyThreadVars():new()
      endif
      oRet := aGlob[nThread]
   endif
   return oRet

CLASS MyThreadVars
   EXPORTED:
      VAR something
ENDCLASS

   
You can add whatever iVars you like to the class.  To use, simply do this
where you need to store/retrieve a value:

Function MyFormFunc( oHtml, oContext )
   
    set value
   Global():something := some_value

    fetch value
   Global():something

    before quitting form-func, kill object:
   Global(TRUE)

Instead of using a class, you could also use my hash routines, both for
aGlob and for it's elements:

Function Global(lKill)
   STATIC hGlob
   local nThread := ThreadID()
   local xRet
 
   DEFAULT lKill to FALSE

   if !lKill
      if hGlob == NIL
         hGlob := xbHash():new()
      endif
      if !hGlob:isKey(nThread)
         hGlob:put(nThread,xbHash():new())
      endif
      xRet := hGlob:fetch(nThread)
   else
      hGlob:put(nThread,NIL)
   endif
   return xRet

This means you don't have to use a class to store value, which means yo
don't have to maintain that class, and now you can store arbitrary values
and retrieve them:

Function MyFormFunc( oHtml, oContext )
   
    set value
   Global():put('somename', some_value)

    fetch value
   Global():fetch('somename')

    before quitting form-func, kill object:
   Global(TRUE)

...or you could use the alternative syntax:

    set value
   Global()=>somename := some_value

    fetch value
   Global()=>somename

I'll be uploading my basic hash class this morning (the indexed hash class
needs a bit more work, but you don't need it for this anyway).

Regards,

Phil Ide

***************************************
* Xbase++ FAQ, Libraries and Sources: *
* goto: http://www.idep.org.uk/xbase  *
***************************************

Lord, give me patience... right now!
Bruce AndersonRe: Socket Write Error Devil
on Sat, 11 Sep 2004 16:03:02 -0500
Perhaps you can educate me on the basics on what the verbose WAA log is
telling me.
Assuming "Worker #" means thread, my socket write error involves a thread
that does not appear to be doing anything.
This happens with a single user on the application.  From the WAA log I see
this:

[mmddyyyy time][#11:Pkg][Service Request Function X]
...
[mmddyyyy time][#11:End][Service Request Function X] elapsed time
[mmddyyyy time][#16:Pkg][SR Func Y]
...
[mmddyyyy time][#16:End][SR Func Y] et
[mmddyyyy time][#3:Pkg][SR Func Z]
...
[mmddyyyy time][#3:End][SR Func Z] et

... (several more of these, then thread #11, with no prior involvement,
suddenly shows up again as...)
[09/01/2004 13:32:51]
*** -----------------------------------------------------------
[09/01/2004 13:32:51] *** worker #11 Error:
[09/01/2004 13:32:51] ***
e:canDefault   :.F.
e:canRetry     :.F.
e:canSubstitute:.F.
e:description  :
e:filename     :
e:genCode      :0
e:operation    :Socket write error
e:osCode       :0
e:severity     :0
e:subCode      :0
e:subSystem    :
e:thread       :2
e:tries        :0
e:cargo        :
Callstack:
CGICHANNEL:GETENV(233)
CONTEXT:GETENV(95)
CONTEXT:GETCOOKIES(73)
SESSION:RESUME(501)
RESUMESESSION(364)
SERVEJOB(295)
SERVEJOBPROTECTION(205)
[09/01/2004 18:31:39]
*** -----------------------------------------------------------
[09/01/2004 18:31:39] *** worker #11 Request not completed
[09/01/2004 18:31:51]
*** -----------------------------------------------------------

...at this point, one by one, the other workers will report the same error
message and WAA must be stopped and relauched to service any requests.

I have no idea what "request" worker #11 has made, etc.  Maybe the problem
is my code, maybe the problem is in the OS, maybe it is hardware?  It seems
to involve only one group of functions that are called as service requests.
Is there a way to put a custom error handler into WAA?
Baffled in Texas
Phil Ide
Re: Socket Write Error Devil
on Mon, 13 Sep 2004 13:50:12 +0100
Bruce,

> ...at this point, one by one, the other workers will report the same error
> message and WAA must be stopped and relauched to service any requests.

THis would be the point where WAA has received a connection request from
waa1gate, which it then passes to a worker thread.  The worker-thread
creates an object to handle that connection and retrieves some POST
variables from the gateway to determine the name of the requested package
and form.  I suspect that the error occurs when the thread attempts to
retrieve these variables, which is why the log doesn't report which
package/form-func is being called.

> I have no idea what "request" worker #11 has made, etc.  Maybe the problem
> is my code, maybe the problem is in the OS, maybe it is hardware?  It seems
> to involve only one group of functions that are called as service requests.
> Is there a way to put a custom error handler into WAA?

There is - using the standard ErrorHandler() routine.  I use this to
capture errors in my own WAA apps (and send me an email of the error).
However, I explicitely reest the error handler back to the original handler
before my form-func terminates, so I don't know whether WAA will
automatically re-assert it's own error handler when control returns to WAA.

Regards,

Phil Ide

***************************************
* Xbase++ FAQ, Libraries and Sources: *
* goto: http://www.idep.org.uk/xbase  *
***************************************

If at first you don't succeed, skydiving is not for you.
Richard A. PulliamRe: Socket Write Error Devil
on Mon, 27 Sep 2004 11:08:50 -0400
I am having the same "Socket write error" problem.  Bruce, did you ever find
a solution?

I am attaching what appears on my error log.  Does not seen to have anything
to do with my code, but an error with GETENV

[09/27/2004 09:22:33][#16:End][//TC/LookupIPAddress] elapsed time [0.19]
[09/27/2004 09:22:36][#7:Pkg][//TC/TakeAction] request at [192.168.4.200]
               *** [#7:Cgi][WAA_ACTION  = Punch Clock
                            WAA_ID      = DEVERS
                            WAA_LOC     = ADMINISTRATION
                            WAA_PACKAGE = TC
                            WAA_FORM    = TakeAction]
[09/27/2004 09:22:36][#7:End][//TC/TakeAction] elapsed time [0.00]
[09/27/2004 09:22:40][#7:Pkg][//TC/AskForPunchIn] request at [192.168.4.200]
               *** [#7:Cgi][WAA_PACKAGE = TC
                            WAA_FORM    = AskForPunchIn
                            WAA_ID      = DEVERS
                            WAA_LOC     = ADMINISTRATION
                            WAA_FIELDS  =
LOCATION,DATE_IN,TIME_IN,DATE_OUT,TIME_OUT
                            WAA_FILTER  = TIMES->ID='DEVERS' .AND.
TIMES->DATE_IN >= CTOD('09/13/2004')]
[09/27/2004 09:22:40][#7:End][//TC/AskForPunchIn] elapsed time [0.26]
[09/27/2004 09:22:51]
*** -----------------------------------------------------------
[09/27/2004 09:22:51] *** worker #7 Error:
[09/27/2004 09:22:51] ***


e:canDefault   :.F.
e:canRetry     :.F.
e:canSubstitute:.F.
e:description  :
e:filename     :
e:genCode      :0
e:operation    :Socket write error
e:osCode       :0
e:severity     :0
e:subCode      :0
e:subSystem    :
e:thread       :7
e:tries        :0
e:cargo        :

Callstack:

CGICHANNEL:GETENV(233)
CONTEXT:GETENV(95)
CONTEXT:GETCOOKIES(73)
SESSION:RESUME(501)
RESUMESESSION(364)
SERVEJOB(295)
SERVEJOBPROTECTION(205)


[09/27/2004 09:22:51]
*** -----------------------------------------------------------
[09/27/2004 09:22:51] *** worker #7 Request not completed
[09/27/2004 09:23:05]
*** -----------------------------------------------------------
[09/27/2004 09:23:05] *** worker #16 Error:
[09/27/2004 09:23:05] ***


e:canDefault   :.F.
e:canRetry     :.F.
e:canSubstitute:.F.
e:description  :
e:filename     :
e:genCode      :0
e:operation    :Socket write error
e:osCode       :0
e:severity     :0
e:subCode      :0
e:subSystem    :
e:thread       :16
e:tries        :0
e:cargo        :

Callstack:

CGICHANNEL:GETENV(233)
CONTEXT:GETENV(95)
CONTEXT:GETCOOKIES(73)
SESSION:RESUME(501)
RESUMESESSION(364)
SERVEJOB(295)
SERVEJOBPROTECTION(205)


[09/27/2004 09:23:05]
*** -----------------------------------------------------------
[09/27/2004 09:23:05] *** worker #16 Request not completed
[09/27/2004 09:29:50]
*** -----------------------------------------------------------


"Bruce Anderson" <banderson@graphical-db.com> wrote in message
news:2aK7QTElEHA.6380@S15147418...
> I continue to have socket write errors.  I do not yet have the pattern to
> predict them, but I believe it must be my code causing them.  I think the
> problem is related to the oContext:openSession() calls.
> Question: Can openSession() be called more than once in a Service Request?
> Assuming an ongoing session and the first instance of openSession() gets
the
> cookie information, what do subsequent openSession() calls get?
>
> I might have made my code too complicated.  I keep the current workspace
and
> recno() for each session in :getCargo().  In my program's logic flow, the
> user-client submits a form, which contains several possible actions
("Save",
> "Delete", "Show"), with the client's choice encoded as a hidden input.
The
> WAA form-function receives the form data and passes oHtml and oContext
onto
> the appropriate internal function for the desired action.  Because of
> session continuity testing, :openSession() :getCargo() can be called more
> than once before I return a HTML page to the client.  I am wondering if
this
> coding and my socket write errors are related.
>
> Curiousity:  What controls which available thread will be used to process
a
> Service Request?  In my simple test instance, I see thread assignments
that
> appear to be chosen randomly.
>
>
Bruce AndersonRe: Socket Write Error Devil
on Mon, 27 Sep 2004 10:54:10 -0500
See my pathetic reply in the socket read problem thread.
Bruce Anderson