Author | Topic: Socket Write Error Devil | |
---|---|---|
Bruce Anderson | Socket 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 Anderson | Re: 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. Pulliam | Re: 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 Anderson | Re: 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 |