Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 7 of 7 total
Thread TServerRequest Queue Issue
Tue, Jun 9 2015 11:09 AMPermanent Link

Mark Brooks

Slikware

Avatar

Tim,

I use TServerRequestQueue in order to perform HTTP requests. Typically I will add a request and then add a subsequent one inside the first request's OnComplete etc. I also use the request data property to pass information through a request call.

It seems that the data property is being zapped (reset to nil) when a new request is added inside the OnComplete handler of the previous request. From some work in the Chrome debugger, I think this is something to do with the algorithm that reuses existing requests rather than creating new ones.

From the WebHTTP unit:

function TServerRequestQueue.GetNewRequest: TServerRequest;
begin
*   Result:=TServerRequest(FAvailableStack.Pop);
*   if (Result=nil) then
     Result:=TServerRequest.Create(Self);
*   else
*      Result.Reset;
end;

If I comment out the "starred" lines (effectively bypassing the reuse algorithm) then the problem goes away as far as I can see. I'm guessing that the request that's being chosen for reuse (and therefore Reset) is actually my "next" one that I'm not yet finished with.

Hope this makes sense.
Mark
Tue, Jun 9 2015 3:06 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Mark,

<< It seems that the data property is being zapped (reset to nil) when a new
request is added inside the OnComplete handler of the previous request. From
some work in the Chrome debugger, I think this is something to do with the
algorithm that reuses existing requests rather than creating new ones. >>

Yeah, it's re-using the request that you're currently using, as expected.
I'm not quite sure what I can do about this (a queue of 1 request would
always show the issue), so you may have to look into caching the relevant
property values before you call GetNewRequest.

Tim Young
Elevate Software
www.elevatesoft.com
Tue, Jun 9 2015 4:01 PMPermanent Link

Mark Brooks

Slikware

Avatar

"Tim Young [Elevate Software]" wrote:

>>Yeah, it's re-using the request that you're currently using, as expected.
>>I'm not quite sure what I can do about this (a queue of 1 request would
>>always show the issue), so you may have to look into caching the relevant
>>property values before you call GetNewRequest.

Ok. I tried assigning the data property as the first line of code within the event handler but it's been reset already at that point, I guess by the GetNewRequest call, along with all the other properties of the Response. This seems a bit unreasonable though, because I've not yet even had a chance to look at it!

Can I just comment out the starred lines (above) to disable the reuse mechanism or will that have undesired consequences? FYI, I have always used the Data property to carry a method pointer through the REST send/receive cycle.I do not recall seeing this in EWB1, or maybe that was subtly different?
Tue, Jun 9 2015 4:09 PMPermanent Link

Mark Brooks

Slikware

Avatar

Mark Brooks wrote:

>>Ok. I tried assigning the data property as the first line of code within the event handler but it's been reset already at >>that point, I guess by the GetNewRequest call, along with all the other properties of the Response. This seems a bit >>unreasonable though, because I've not yet even had a chance to look at it!

>>Can I just comment out the starred lines (above) to disable the reuse mechanism or will that have undesired >>consequences? FYI, I have always used the Data property to carry a method pointer through the REST >>send/receive cycle.I do not recall seeing this in EWB1, or maybe that was subtly different?

Scratch that Tim. I think I have a plan. Will try later.
Tue, Jun 9 2015 5:16 PMPermanent Link

Mark Brooks

Slikware

Avatar

Mark Brooks wrote:

>>Scratch that Tim. I think I have a plan. Will try later.

All good. Cache works perfectly. Just one to be aware of. Thanks Tim.
Wed, Jun 10 2015 4:11 AMPermanent Link

Matthew Jones

Mark Brooks wrote:

>  I think I have a plan.

What was the solution? Chaining calls is going to be common, so knowing
how to do this nicely would be good to know.
Wed, Jun 10 2015 5:52 AMPermanent Link

Mark Brooks

Slikware

Avatar

"Matthew Jones" wrote:

>>What was the solution? Chaining calls is going to be common, so knowing
>>how to do this nicely would be good to know.

Well, I'm not sure how this might affect other users. I actually have my own wrapper around the TServerQueue for a number of reasons, not least of which because I want to trap the OnComplete within the wrapper and surface a number of other events within it, then also call the user's specified callback function. I do this by using the Request Data property to hold a "dummy" instantiated class, that in turn contains a callback method of the appropriate type. I think it's the only way to achieve this since you can't fool EWB into treating the Data property as a method pointer.

Because I use this mechanism, I need to ensure that I free the dummy object at the end of the internal callback. However, because I call the user's callback from within here, AND because that in turn may well add a new request to the server queue (the "chaining" as you call it) AND because there is a reuse mechanism in place for requests AND because this mechanism calls the Request Reset method, it's quite possible for my Data property to be set to nil. This means that I can't free it.

The answer is to cache any properties of the Request that you may wish to work with before any subsequent requests are added to the queue.

I hope this makes sense?

Mark
Image