Open minhletn opened 6 years ago
When you say "AuthenticationRequest" you mean they get stuck in ASP.NET, or after the data portal itself has been invoked?
Hi rockfordlhotka,
AuthenticateRequest is the state showed in IIS > WorkerProcesses > [AppPoolName] when the requests are stuck, after the data portal is invoked, e.g calling fetch
When this problem happens, there are many requests there in that state for a very long time
This sounds like it is during the ASP.NET pipeline, and before the data portal has been invoked. The data portal isn't invoked until after ASP.NET/WCF have authenticated the request.
Do you have code in the server that handles the ASP.NET authentication event (global.asax), or a custom handler, or anything like that?
Hi rockfordlhotka,
Thanks very much for getting back to me
There's no logic in global.asax to handle AuthenticateRequest, but there's a class which we use that extends Csla.Server.Hosts.Silverlight.WcfPortal to compress and decompress request and response data
If the logic to compress/decompress has some sort of memory issue (e.g memory stream is not closed properly), do you think it cause the problem?
public class CompressedHost : Csla.Server.Hosts.Silverlight.WcfPortal
{
protected override Csla.Server.Hosts.Silverlight.CriteriaRequest ConvertRequest(Csla.Server.Hosts.Silverlight.CriteriaRequest request)
{
Csla.Server.Hosts.Silverlight.CriteriaRequest returnValue = new Csla.Server.Hosts.Silverlight.CriteriaRequest();
returnValue.ClientContext = CompressionUtility.Decompress(request.ClientContext);
returnValue.GlobalContext = CompressionUtility.Decompress(request.GlobalContext);
if (request.CriteriaData != null)
returnValue.CriteriaData = CompressionUtility.Decompress(request.CriteriaData);
returnValue.Principal = CompressionUtility.Decompress(request.Principal);
returnValue.TypeName = request.TypeName;
return returnValue;
}
protected override Csla.Server.Hosts.Silverlight.UpdateRequest ConvertRequest(Csla.Server.Hosts.Silverlight.UpdateRequest request)
{
Csla.Server.Hosts.Silverlight.UpdateRequest returnValue = new Csla.Server.Hosts.Silverlight.UpdateRequest();
returnValue.ClientContext = CompressionUtility.Decompress(request.ClientContext);
returnValue.GlobalContext = CompressionUtility.Decompress(request.GlobalContext);
returnValue.ObjectData = CompressionUtility.Decompress(request.ObjectData);
returnValue.Principal = CompressionUtility.Decompress(request.Principal);
return returnValue;
}
protected override Csla.Server.Hosts.Silverlight.WcfResponse ConvertResponse(Csla.Server.Hosts.Silverlight.WcfResponse response)
{
Csla.Server.Hosts.Silverlight.WcfResponse returnValue = new Csla.Server.Hosts.Silverlight.WcfResponse();
returnValue.GlobalContext = CompressionUtility.Compress(response.GlobalContext);
returnValue.ObjectData = CompressionUtility.Compress(response.ObjectData);
returnValue.ErrorData = response.ErrorData;
return returnValue;
}
}
The compress, decompress code are as below
public static int _compressionMethod = ICSharpCode.SharpZipLib.Zip.Compression.Deflater.BEST_SPEED;
public static byte[] Compress(byte[] byteData)
{
byte[] compressedData = null;
if (byteData != null)
{
using (MemoryStream ms = new MemoryStream())
{
ICSharpCode.SharpZipLib.Zip.Compression.Deflater defl = new ICSharpCode.SharpZipLib.Zip.Compression.Deflater(_compressionMethod, false);
using (Stream s = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream(ms, defl))
s.Write(byteData, 0, byteData.Length);
compressedData = ms.ToArray();
}
}
return compressedData;
}
public static byte[] Decompress(byte[] byteInput)
{
byte[] bytResult = null;
if (byteInput != null)
{
using (MemoryStream ms = new MemoryStream(byteInput, 0, byteInput.Length))
{
string strResult = String.Empty;
byte[] writeData = new byte[4096];
using (Stream s2 = new ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(ms))
bytResult = ReadFullStream(s2);
}
}
return bytResult;
}
private static byte[] ReadFullStream(Stream stream)
{
byte[] buffer = new byte[32768];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
I don't think that is likely, though not disposing a stream could cause a memory leak, so that's not good on a server.
The Silverlight version of WcfPortal
doesn't do a whole lot. The Fetch
method, for example, does this:
Fetch
method on a MobileRequestProcessor
The MobileRequestProcessor
then does this:
Fetch
method on the concrete data portal instanceThe concrete data portal (Csla.Server.DataPortal
) is the thing that does all the real work behind any data portal host (WCF, Http, etc.).
So the data portal does authorize the request, but doesn't authenticate it in any way - the assumption is that any authentication occurred before the data portal was invoked at all.
As a troubleshooting thing, you could maybe put some logging code into your compression class - just log that you got that far, so you'd know if the data portal was actually invoked, or if the failure occurs somewhere in WCF itself.
Question We've encountered an issue when many requests to the portal are stuck in AuthenticteRequest stage for very long (10-20 minutes) and CPU is high
There are many requests stuck in IIS, all with AuthenticateRequest stage `
`
The binding is set up like this in the web.config file `
`
I'm pretty new to CSLA and just wonder if any has seen this before and know the way to fix?
Version and Platform CSLA version: 4.3.14 OS: Windows Platform: Silverlight