PollingDuplex multiple mode timeouts demystified

The new MultipleMessagesPerPoll mode added to PollingDuplex in Silverlight 4, comes with some new timeouts , so I thought it would be useful to post a detailed description of how those work. Unfortunately this is not currently covered by our documentation, which is something we are looking to address in upcoming documentation refreshes.

This is a fairly advanced topic, and the default settings should work well for most customers, so only modify these if you are encountering an issue, and you are fairly confident a timeout is causing the problem. The information below applies only to the new multiple messages mode, which is activated by setting duplexMode="MultipleMessagesPerPoll" on the PollingDuplex binding or binding element.

One important thing in the text below is to differentiate between infrastructure messages (such as polls in this case) and application messages. Infrastructure messages such as polls (and poll responses) are not initiated by or surfaced to the user – they are just an implementation detail of the protocol. Application messages are messages that actually originated in the user code. They can be separated into client-to-server messages (“requests coming from client”) or server-to-client messages (“server responses to requests coming from client” and “requests coming from server”). There is no “client responses coming from server” because of the way polling works. I will try to stick to this terminology in the text below.

Most of the new timeouts live on the server. All class and member names refer to the server-side System.ServiceModel.PollingDuplex.dll that ships in the “Server” folder of the Silverlight SDK. Take a look at the following diagram for a visual explanation:

PollingDuplex Timeouts

The diagram shows an incoming poll and the chunked response being returned containing application messages. The first server-to-client application message is greater than 16/32KB (16 for self-hosted PollingDuplex services, 32KB for IIS-hosted), so the chunked response is flushed and the message should arrive immediately at the client. The then client sends a smaller application messages, but the total size does not reach 16/32KB, so the chunked response is not flushed. To prevent the message from getting stuck, the chunked response will be flushed and closed when the MaxOutputDelay timer expires, and the message will then be delivered to the client. Then the client sends two application messages coming in from the client and the timeouts associated with those.

Here is a more detailed description of each timeout.

ServerPollTimeout

  • Set it here
    • System.ServiceModel.PollingDuplexHttpBinding.ServerPollTimeout
    • System.ServiceModel.Channels.PollingDuplexBindingElement.ServerPollTimeout
  • Definition: Time the server holds the poll request prior to sending an empty poll response to the client. After the first outgoing server-to-client application message (either server response to request coming from client or request coming from the server) gets sent, this timer stops being used, and MaxOutputDelay kicks in. Bound to the client dispatcher (HTTP request / response)
  • Default: 15 s

MaxOutputDelay

  • Set it here
    • System.ServiceModel.PollingDuplexHttpBinding.MaxOutputDelay
    • System.ServiceModel.Channels.PollingDuplexBindingElement.MaxOutputDelay
  • Definition: Time between the last outgoing server-to-client application message and the HTTP response being closed; it’s reset with each new outgoing message being dequeued. Closing the response ensures that all messages are flushed and no message will take longer than MaxOutputDelay to be delivered to the client. Bound to the client dispatcher.
  • Default: 200 ms

PollHeartbeatTimeout

  • Not settable – this is an internal property
  • Definition: Timer which is started when a poll response is sent to the client, and stopped when the next poll for that dispatcher is received. Bound to the client dispatcher. If the timeout is reached, all the channels bound to the dispatcher are faulted. This is how we determine if a client “is still there”.
  • Value:  4 * ServerPollTimeout + 30 s (after polling has started), 2 * ServerPollTimeout + 15 s (if server has not received the first poll from the client)

InactivityTimeout

  • Set it here
    • System.ServiceModel.PollingDuplexHttpBinding.InactivityTimeout
    • System.ServiceModel.Channels.PollingDuplexBindingElement.InactivityTimeout
  • Definition: Timer which is reset when an application messages is received by the channel. If the timeout is reached, the channel is faulted. Bound to the client session. Note that this not affected by polls, contrary to the way this same timeout behaves with infrastructure messages on other bindings (as described here). So effectively this is the same as ReceiveTimeout.
  • Default: 10 min

ReceiveTimeout

  • Set it here
    • System.ServiceModel.Channels.Binding.ReceiveTimeout
  • Definition: Timer which is reset when the ServiceModel layer pumps an application message from a PollingDuplex channel. If the timeout is reached, the channel is aborted. Infrastructure messages such as polls don’t affect this timeout. Bound to the client session (channel).
  • Default: 10 min

 

On the client side, we also have some timeouts that may be of interest. All class and member names below refer to the client-side System.ServiceModel.PollingDuplex.dll that ships in the “Client” folder of the Silverlight SDK.

ClientPollTimeout

InactivityTimeout

Hope this is useful.

-Yavor Georgiev
Program Manager, WCF