hi, i’ve started playing around with the Async_Ex service function calls and have a few questions:
the create:
class function Create(const aUrl: string; aDefaultNamespaces: string = ‘’): IProxyService_AsyncEx; overload;
it seems that i can’t get this one to work, i do include the /BIN but i guess it does not resolve to the right channel… any prerequisites using this?
channel and message:
my these be shared when using the async_ex functions or do these have to have their own channel and message?
the callback:
is this called in the main thread or do i need to foresee threaded entry?
can i have multiple async_ex.beginxxx calls all using the same callback?
if so what is the lifetime of the Endxxx call of (const aRequest: IROAsyncRequest)?
if i can’t use the same callback for multiple beginxxx calls, do i always nil the aRequest or not? (in the photo sample you check the intf: if aRequest = ClientForm.fDownload then ClientForm.fDownload := nil;)
Check the Phone Photo Server sample - it shows usage of AsyncEx interfaces.
You should include full URL with /Bin - it will allow to detect valid message.
general rules - you should include desired channel/message into uses section.
it is used for detecting what channel/message should be used.
you may add registration manually for desired channel if it is missed it.
own channel/message are used for AsyncEx fro avoiding AV issues when the same data is read/wtitten from different threads.
You can retrieve channel/message from IROAsyncRequest interface.
it is called in background thread
You can use the same callback method for handling begin* methods.
for example - you have BeginSum and BeginGetServerTime methods. if same callback is used for both methods you have to call EndSum or EndGetServerTime in that callback. ofc, you can put some additional info into UserData and detect valid method, but I think better to have own callback per method.
server response is stored in object associated with IROAsyncRequest. this object is passed to your callback method.
in this sample we allow only one download request so we cancel previous one:
if (fDownload <> nil) then fDownload.Cancel;
...
fDownload := GetService.BeginDownloadPhoto(lItem.Name,Callback_DownloadPhoto,lItem);
so we clear fDownload once download callback was finished.
it is used for detecting what channel/message should be used.
you may add registration manually for desired channel if it is missed it.
the uses clause is ok, but the channel does not get recognised, we use plain tcp by the way, not https, so my test url is ‘localhost:8888/BIN’
is this supposed to work?
it is called in background thread
You can use the same callback method for handling begin* methods.
so if i execute 5 beginAAA calls (so the same function) all with the same callback interface, and since the callback is being called threaded, i should include thread code that will synchronise with main thread yes? or will the the callback for the beginAAA func be like a fifo callback?
in this sample we allow only one download request so we cancel previous one:
if (fDownload <> nil) then fDownload.Cancel;
...
fDownload := GetService.BeginDownloadPhoto(lItem.Name,Callback_DownloadPhoto,lItem);
so we clear fDownload once download callback was finished.
no i was talking about the callback procedure which has:
finally
if aRequest = ClientForm.fDownload then ClientForm.fDownload := nil;
so this frees the iroasyncrequest but only if it was the one that was created in the beginAAA call, but why only if it is the same? since the call has ended, shouldn’t it be always freed?
so this is a const param, i can’t nil this, so the async_ex object will take care of this?
since i putted all beginAsync_ex() result into the same var i will have created dangling interface references yes?
if so i need to hold some kind of list of them?
or can i simply ignore the interface result of the beginAsync_ex call?
in fact do i need the interface reference at all?
No issue at all. this means that you can work only with last request.
actual IROAsyncRequest is stored internally and it will be passed to your callback as a parameter.
if you don’t need to do anything with request (check state, cancel request, etc), you can just ignore result of begin* method like
let’s say i have a bulk of things to do, fetching a status of persons remotely
this is a RO service
so i’m processing an list of 100 persons which i want to check using this async_ex method
so a simple approach is to loop over this list and issue the beginAsync_ex call
i guess creating a TTask to execute that call is overhead
now i only have 1 callback procedure
which will be executed threaded, so simultanious entries may occur
if i’m using a thread safe list i guess i’m fine, so i can save the result back for the correct person (i’ll probably either store the IROAsyncRequest or use UserData to match the request with the correct list entry)
now here comes the question: what is the best way to detect the completion of all calls?
in other words, at a certain moment i need to be able to detect if the bulk operation is finished…
lol
no no, that wat about something else, dangling interface references
so more like a threadlist of personstatus objs
that personstatus class had a IROAsyncRequest member in which i could store the reference
and in the callback i could check aRequest matching that personstatus member
main issue is how to detect if all calls completed (or did not for that matter)
i could loop over that list keeping track of a response for each entry but then again if a call for some reason whatsoever does not result in a callback i will not know about it and wait…
unless the RO infrastructure has an internal timeout which would do the trick?
but just to be sure:
in the callback method:
.Cancelled is always False right? (except when I trigger .Cancel)
.Done is always true?
problem is that it seems that when the service is not running, i do get the callback with .cancelled false and .done true, leading me to conclude that the .beginxxx method succeeded but in fact it didn’t cause there was no endpoint…
what is a solid way to determine failure of the service side in the client?