[Progress Communities] [Progress OpenEdge ABL] Forum Post: RE: Rare .Net OpenClient Error Related to Concurrent Creation of AppObject (CONNECT FAILURE

Status
Not open for further replies.
D

dbeavon

Guest
>> Can you give me an idea about the usage patterns you have in your application? For "state-reset" code (aka. "session managed" pasoe clients), we create brand new connections and new appobjects. In theory they are totally independent of each other. Internally there are static members that are shared... not by my choice... and I had spent a lot of time digging into this back in 2017 (per case 00375301 / bug PSC00355194). For example, here is the callstack where two appobjects were stepping on each other. Notice at the top of the stack there is a static Hashtable with no concurrency protection. I didn't ever create my own repro for this, hoping that Progress would pick up the ball and do some of that work. > mscorlib.dll!System.Collections.Hashtable.Insert(object key, object nvalue, bool add) Unknown Progress.o4glrt.dll!Progress.SupportClass.BufferedStreamManager.BufferedStreamsHashTable.MarkPosition(int index, System.IO.Stream stream) Unknown Progress.o4glrt.dll!Progress.UBroker.Client.TcpClientMsgInputStream.readMsg() Unknown Progress.o4glrt.dll!Progress.UBroker.Client.BrokerSystem.readMsg() Unknown Progress.o4glrt.dll!Progress.UBroker.Client.BrokerSystem.connectPacket(string requestID, string username, string password, string clientInfo, bool fToBroker, int clntAskCaps, out int connAckFlags) Unknown Progress.o4glrt.dll!Progress.UBroker.Client.BrokerSystem.processConnect(string requestID, object connectionInfo, string username, string password, string clientInfo, bool fToBroker, int clntAskCaps, out int connAckFlags) Unknown Progress.o4glrt.dll!Progress.UBroker.Client.BrokerSystem.connect(string requestID, string url, string username, string password, string clientInfo, out int connAckFlags) Unknown Progress.o4glrt.dll!Progress.Open4GL.DynamicAPI.Session.connect(string requestID, string url, string userId, string password, string clientInfo, int proxyGenVersion) Unknown Progress.o4glrt.dll!Progress.Open4GL.DynamicAPI.SessionPool.BrokerSessionList.reserveSession(bool fCreateNewSession) Unknown Progress.o4glrt.dll!Progress.Open4GL.DynamicAPI.SessionPool.reserveSession(bool fCreateNewSession, Progress.Open4GL.DynamicAPI.SessionPool.PickList pickList, bool fRefresh) Unknown Progress.o4glrt.dll!Progress.Open4GL.DynamicAPI.SessionPool.createSession() Unknown Progress.o4glrt.dll!Progress.Open4GL.DynamicAPI.SessionPool.initializePool() Unknown Progress.o4glrt.dll!Progress.Open4GL.DynamicAPI.SessionPool.SessionPool(string appName, Progress.Open4GL.DynamicAPI.IPoolProps properties, Progress.Common.EhnLog.IAppLogger log, string poolName, string requestID) Unknown Progress.o4glrt.dll!Progress.Open4GL.DynamicAPI.SessionPool.createPool(string appName, Progress.Open4GL.DynamicAPI.IPoolProps properties, Progress.Common.EhnLog.IAppLogger log, string requestID) Unknown Progress.o4glrt.dll!Progress.Open4GL.Proxy.ProObject.initAppObject(string appName, Progress.Open4GL.DynamicAPI.IPoolProps properties, Progress.Common.EhnLog.IAppLogger log, string requestID) Unknown Progress.o4glrt.dll!Progress.Open4GL.Proxy.AppObject.initAppObject(string appName, Progress.Open4GL.DynamicAPI.IPoolProps properties, Progress.Common.EhnLog.IAppLogger log, string requestID, int proxyGenVersion) Unknown LumberTrackProxy.dll!UFP.LumberTrack.AppServer.Proxy.LumberTrackProxy.LumberTrackProxy(Progress.Open4GL.Proxy.Connection connectObj, bool useWebConfigFile) Unknown I suspect that this error was most likely to happen the *first* time an openclient was used in the lifetime of an appdomain, *if* it was being used on multiple threads simultaneously (via a Parallel.Foreach or similar). In certain of our hosting contexts, the appdomains are cycled regularly. For example SSRS can host our custom code and it cycles appdomains quite frequently. Some of our windows services and web applications get cycled quite frequently too. I suspect that if you were to repeatedly restart a new appdomain in a loop, and if you were to write code that does a Parallel.Foreach when the appdomain first started, and if the code in the Parallel.Foreach tried to "new" an independent AppObject in the loop ... then that is where you would eventually find the bug. Again I don't think that anyone ever built that repro to actually demonstrate the bug; I think they probably just did a code-review and changed the code by adding better protection around the static Hashtable. The existence of a bug isn't what bothers me. Every piece of software has bugs. What bothers me is the impression that the exceptions are deliberately opaque, and that the inner exceptions and callstacks are being hidden. The real annoyance to me in this case was the amount of work that was involved - simply to get a meaningful callstack like the one you see above. The openclient for .Net never seems to give helpful stacks and the root problem is often obscured by layers of subsequent/misleading exceptions that are re-thrown afterwards. As I recall, I think I had to use procdump or something similar to capture the first-chance exception (procdump: ProcDump - Windows Sysinternals ). Hopefully this grumbling is somewhat constructive. Maybe OE 12 will give us some improvement in the openclient exceptions!

Continue reading...
 
Status
Not open for further replies.
Top