J
Joseph Geretz
I have a transaction processing pipeline which is built on HTTP. Basically,
the client submits transactions via HTTP, the transaction is processed on
the server and the result is sent back to the client. (It's actually a bit
more complex, but that basic paradigm will suffice for the basis of my
question.)
The HTTP request/response looks like this:
Stream newStream = Req.GetRequestStream();
newStream.Write(PostBytes, 0, PostBytes.Length);
newStream.Close();
m_Resp = (HttpWebResponse)Req.GetResponse();
Pretty standard. In practice, posting the small amount of transaction data
up to the transaction handler is quick, milliseconds. Waiting for the
transaction to process on the server and for the response to return is the
slow part.
Since the client is basically submitting data, and doesn't care about the
response, and since 98% of all transactions succeed, our user base is
contending that processing this transaction with a synchronous
request/response pair is a waste of their time. I've been asked to decouple
the request from the response so that the client can continue executing
immediately after posting the data up to the server. (Yes, we'll incur added
complexity for handling responses, especially error responses. However,
since the vast majority of transactions succeed, we feel that the
performance increase will justify the added complexity. Let's leave that
issue alone for now.)
My first inclination was to investigate asynchronous HTTP which I've heard a
bit about over recent months. However, the more I think about this, the more
I'm coming to the conclusion that I'm not necessarily looking for
asynchronous HTTP. Rather, I think that what I am looking for is
'responseless' HTTP. Is there such a thing?
I seems to me that what I need to do is something like the following:
Stream newStream = Req.GetRequestStream();
newStream.Write(PostBytes, 0, PostBytes.Length);
newStream.Close();
m_Resp = "SUBMITTED"; // And continue...
....where the last line is a pseudo representation for simply returning a
response to the client without actually waiting for the HTTP response from
the upstream server. Is this a valid way to execute an HTTP transaction?
Will the transaction continue to execute on the Server even though the
client has essentially disappeared?
If this will execute properly, then I think I have my architectural
approach. The client will post up to the server a transaction ID (GUID)
along with a flag indicating whether it is going to wait for a response, or
not. If the client will await a response, then the server will send that
response back to the client via a Response.Write, exactly as is happening
today. If the client is not awaiting a response, then the server won't send
a response, rather it will POST the response back to the originating client,
along with the transaction ID so that the client (the original client - now
its acting as a server) can correlate the POSTed response to the original
request and make the proper final status entry into the database.
Do you see this as being better or worse than the alternative, which would
be to implement an asynchronous response?
Stream newStream = Req.GetRequestStream();
newStream.Write(PostBytes, 0, PostBytes.Length);
newStream.Close();
Req.BeginGetResponse(yadayada, yada);
The latter approach would make sense where the client doesn't provide a
public web interface over which to receive status via POST-back. Also, it
eliminates the need to pass the transaction ID, since an HTTP response is
naturally paied with its originating request. In my case though, the
transaction pipeline is already bidirectional, transactions pass both ways
through the pipeline, and so every web site is already configured to act as
a transaction client or server. Assigning and passing the tracking
transaction ID, also not a big deal. It seems to me that terminating the
transaction and handling status via a separate reverse direction POST is
going to result in a cleaner, less error prone and more performant system
tham messing around with asynchronous responses. But maybe I'm just an old
luddite! ;-)
I appreciate any advice which you can offer.
Thanks!
Joseph Geretz
the client submits transactions via HTTP, the transaction is processed on
the server and the result is sent back to the client. (It's actually a bit
more complex, but that basic paradigm will suffice for the basis of my
question.)
The HTTP request/response looks like this:
Stream newStream = Req.GetRequestStream();
newStream.Write(PostBytes, 0, PostBytes.Length);
newStream.Close();
m_Resp = (HttpWebResponse)Req.GetResponse();
Pretty standard. In practice, posting the small amount of transaction data
up to the transaction handler is quick, milliseconds. Waiting for the
transaction to process on the server and for the response to return is the
slow part.
Since the client is basically submitting data, and doesn't care about the
response, and since 98% of all transactions succeed, our user base is
contending that processing this transaction with a synchronous
request/response pair is a waste of their time. I've been asked to decouple
the request from the response so that the client can continue executing
immediately after posting the data up to the server. (Yes, we'll incur added
complexity for handling responses, especially error responses. However,
since the vast majority of transactions succeed, we feel that the
performance increase will justify the added complexity. Let's leave that
issue alone for now.)
My first inclination was to investigate asynchronous HTTP which I've heard a
bit about over recent months. However, the more I think about this, the more
I'm coming to the conclusion that I'm not necessarily looking for
asynchronous HTTP. Rather, I think that what I am looking for is
'responseless' HTTP. Is there such a thing?
I seems to me that what I need to do is something like the following:
Stream newStream = Req.GetRequestStream();
newStream.Write(PostBytes, 0, PostBytes.Length);
newStream.Close();
m_Resp = "SUBMITTED"; // And continue...
....where the last line is a pseudo representation for simply returning a
response to the client without actually waiting for the HTTP response from
the upstream server. Is this a valid way to execute an HTTP transaction?
Will the transaction continue to execute on the Server even though the
client has essentially disappeared?
If this will execute properly, then I think I have my architectural
approach. The client will post up to the server a transaction ID (GUID)
along with a flag indicating whether it is going to wait for a response, or
not. If the client will await a response, then the server will send that
response back to the client via a Response.Write, exactly as is happening
today. If the client is not awaiting a response, then the server won't send
a response, rather it will POST the response back to the originating client,
along with the transaction ID so that the client (the original client - now
its acting as a server) can correlate the POSTed response to the original
request and make the proper final status entry into the database.
Do you see this as being better or worse than the alternative, which would
be to implement an asynchronous response?
Stream newStream = Req.GetRequestStream();
newStream.Write(PostBytes, 0, PostBytes.Length);
newStream.Close();
Req.BeginGetResponse(yadayada, yada);
The latter approach would make sense where the client doesn't provide a
public web interface over which to receive status via POST-back. Also, it
eliminates the need to pass the transaction ID, since an HTTP response is
naturally paied with its originating request. In my case though, the
transaction pipeline is already bidirectional, transactions pass both ways
through the pipeline, and so every web site is already configured to act as
a transaction client or server. Assigning and passing the tracking
transaction ID, also not a big deal. It seems to me that terminating the
transaction and handling status via a separate reverse direction POST is
going to result in a cleaner, less error prone and more performant system
tham messing around with asynchronous responses. But maybe I'm just an old
luddite! ;-)
I appreciate any advice which you can offer.
Thanks!
Joseph Geretz