Forum Discussion

Kirk_Jackson's avatar
Kirk_Jackson
Icon for Nimbostratus rankNimbostratus
May 01, 2018

STREAM::expression and "thread safety"

Hi,

I don't think "thread safety" is the right term here, but kinda helps explain my question.

STREAM::expression can be changed in an iRule, and the documentation says it affects "this connection only":

https://devcentral.f5.com/wiki/irules.stream__expression.ashx

What happens if I'm changing this in HTTP_RESPONSE and there's multiple requests / responses on the same TCP connection? Will the STREAM::expression set in one HTTP_RESPONSE pollute the value set in another? Do multiple HTTP_REQUESTs and HTTP_RESPONSEs happen at the same time if there's many concurrent requests from the same browser?

Likewise, for STREAM::enable. I've already come across the issue where enabling STREAM::enable in one HTTP_RESPONSE causes other HTTP requests to also get processed. I think this is because the stream processing is enabled for a connection.

I now use the pattern:

when HTTP_REQUEST {
    STREAM::disable
}

when HTTP_RESPONSE {
    if {some condition holds} {
        STREAM::enable
    }
}

This means that the STREAM processing is disabled at the beginning of every request.

However, does this lead to a race condition if there are multiple requests executing in parallel? If response enables the stream, is it visible to other responses on the same connection?

i.e.

REQUEST 1               REQUEST 2

HTTP_REQUEST            
(disable stream)

                                    HTTP_REQUEST
                                    (disable stream)
HTTP_RESPONSE
condition is true:
(enable stream)

(stream processing occurs)

                                    HTTP_RESPONSE
                                    condition is false:
                                    (leave stream as-is)

                                    (stream processing occurs anyway)
  • For the HTTP profile, HTTP pipelining is enabled by default, but current browsers do not enable pipelining by default.

     

    If pipelining is enabled on the HTTP profile, as per

     

    AskF5 Home > Knowledge Center > BIG-IP LTM > BIG-IP Local Traffic Management: Profiles Reference > Services Profiles

     

    Support for pipelining

     

    Normally, a client cannot initiate a request until the previous request has received a response. HTTP/1.1 pipelining allows clients to initiate multiple requests even when prior requests have not received a response. Note, however, that each initiated request is still processed sequentially; that is, a request in the queue is not processed until the previous request has received a response.

     

    By enabling support for pipelining on the BIG-IP® system, you remove the need to enable pipelining on the destination server itself. By default, this feature is enabled.

     

    So you will always get a sequential HTTP_REQUEST/HTTP_RESPONSE for an HTTP profile, and there should be no concerns about event ordering.

     

    I'll provide a separate answer for the HTTP/2 profile when I get some more information.

     

  • HTTP/2 allows multiplexed requests.

     

    The individual HTTP/2 requests in the TCP connection will be separated into Streams (based on Stream ID) at the HTTP_REQUEST and responses combined back into the connection at HTTP_RESPONSE.

     

    Between those two events, each Stream is an individual Stream context, and items such as TCL variables and STREAM::expression only exist in that Stream context. You cannot access the Connection context from within the Stream context, so if you need to store a Connection variable for access from within the Stream context, it needs to be stored globally (i.e using table).

     

    So from HTTP_REQUEST to HTTP_RESPONSE, STREAM:: is limited in scope to the Stream, and will not interfere with other request/responses.