ServerXmlHttpRequest sometimes hangs when doing POST

I have a job that periodically does some work with ServerXmlHttpRquest to do an HTTP POST . Work is performed every 60 seconds.

And usually it works without problems. But there are about 1 out of 50,000 chances (every two or three months) that it will hang:

 IXMLHttpRequest http = new ServerXmlHttpRequest(); http.open("POST", deleteUrl, false, "", ""); http.send(stuffToDelete); <---hang 

When it freezes, even the Task Scheduler (with the ability to turn on the task if it takes more than 3 minutes to start) can complete the task. I have to connect to the network of the remote client, get on the server and use the task manager to kill the process.

And then it's good for another month or three.

In the end, I started using task manager to dump the process,

enter image description here

so that I can analyze where the hang is. After five crash dumps (in the last 11 months or so), I get a consistent image:

 ntdll.dll!_NtWaitForMultipleObjects@20 () KERNELBASE.dll!_WaitForMultipleObjectsEx@20 () user32.dll!MsgWaitForMultipleObjectsEx() user32.dll!_MsgWaitForMultipleObjects@20 () urlmon.dll!CTransaction::CompleteOperation(int fNested) Line 2496 urlmon.dll!CTransaction::StartEx(IUri * pIUri, IInternetProtocolSink * pOInetProtSink, IInternetBindInfo * pOInetBindInfo, unsigned long grfOptions, unsigned long dwReserved) Line 4453 C++ urlmon.dll!CTransaction::Start(const wchar_t * pwzURL, IInternetProtocolSink * pOInetProtSink, IInternetBindInfo * pOInetBindInfo, unsigned long grfOptions, unsigned long dwReserved) Line 4515 C++ msxml3.dll!URLMONRequest::send() msxml3.dll!XMLHttp::send() Contoso.exe!FrobImporter.TFrobImporter.DeleteFrobs Line 971 Contoso.exe!FrobImporter.TFrobImporter.ImportCore Line 1583 Contoso.exe!FrobImporter.TFrobImporter.RunImport Line 1070 Contoso.exe!CommandLineProcessor.TCommandLineProcessor.HandleFrobImport Line 433 Contoso.exe!CommandLineProcessor.TCommandLineProcessor.CoreExecute Line 71 Contoso.exe!CommandLineProcessor.TCommandLineProcessor.Execute Line 84 Contoso.exe!Contoso.Contoso Line 167 kernel32.dll!@BaseThreadInitThunk @12() ntdll.dll!__RtlUserThreadStart() ntdll.dll!__RtlUserThreadStart@8 () 

So, I am doing ServerXmlHttpRequest.send and it never returns. He will sit there for several days (forcing the system to skip financial transactions, until Sunday night I get a call that he broke).

This will not help if someone does not know how to debug the code, but the registers in the inhibited stream during the dump:

 EAX 00000030 EBX 00000000 ECX 00000000 EDX 00000000 ESI 002CAC08 EDI 00000001 EIP 732A08A7 ESP 0018F684 EBP 0018F6C8 EFL 00000000 
  • Windows Server 2012 R2
  • Microsoft IIS / 8.5

ServerXmlHttpRequest Default Timeouts

You can use serverXmlHttpRequest.setTimeouts(...) to configure four classes of timeouts:

  • resolveTimeout . This value is used to match host names (for example, "www.microsoft.com") to IP addresses; the default value is infinite , which means no timeout.
  • connectTimeout : a long integer. The value is used to establish a communication socket with the target server with a minimum default timeout value of 60 seconds.
  • sendTimeout . This value is used to send a separate packet of request data (if any) in the connecting socket to the target server. A large request sent to the server is usually split into several packets; send timeout is used to send each packet individually. The default value is 30 seconds .
  • receiveTimeout . The value is used to receive the response data packet from the target server. Large responses will be split into multiple packages; A receive timeout is used to retrieve each packet of data from the socket. The default value is 30 seconds .

KB305053 (a server that decides to keep the connection open will cause serverXmlHttpRequest to wait for the connection to close) it seems like this could probably be the problem. But the 30th default timeout would take care of that.

Possible Workaround - Add Yourself to Work

Windows Task Scheduler cannot complete the task; even if this option is enabled.

I will consider using the Windows Job API to add my own process to work and SetInformationJobObject to set a time limit on my process:

to limit my process to three minutes of runtime:

PerProcessUserTimeLimit
If LimitFlags specifies JOB_OBJECT_LIMIT_PROCESS_TIME , this member is a user run-time mode process, in 100 nanosecond ticks. Otherwise, this element is ignored.

The system periodically checks to determine whether each process associated with the task has more user-mode time than the set limit. If so, the process ends.

If the task is nested, the effective limit is the most restrictive limit in the task chain.

Although, since the task scheduler uses Job objects to also limit the time of the task, I do not hope that the task object can also limit the work.

Change Job objects cannot limit the process to the process time β€” only the user . And with a process waiting for an object, it will not accumulate any user time - of course, not for three minutes.

Reading bonuses

0
source share
1 answer

Consider moving to a new, supported API.

The msxml3.dll library is no longer supported and is only supported for compatibility reasons. In addition, there are a number of security and stability improvements included in msxml4.dll (and newer) that you skip.

+1
source

All Articles