Is CURRENT-REQUEST-INFO handled differently for asynchronous

Posted by mopfer on 20-Apr-2015 14:59

Hi, We are running OpenEdge 11.4, and for this particular question the client is a prowin32 session and the appserver is a state-free appserver. If we connect to the appserver and run code in the server program that creates a client-principal, we can access that client-principal from the appserver on subsequent calls by using the SESSION:CURRENT-REQUEST-INFO object. That consistently works fine as long as the client is making synchronous calls. However, if the client makes an asynchronous call, SESSION:CURRENT-REQUEST-INFO in the server program comes up NULL. We can add code to the client program to set a specific client-principal to the client-side REQUEST-INFO object before each asynchronous call and the server program will see that OK, but it will not automatically see the client-principal that was originally assigned unless we change the calls to be synchronous. The documentation of the CURRENT-REQUEST-INFO doesn't give any indication that an asynchronous call would be handled differently than a synchronous call. The documentation of the client-side REQUEST-INFO object does seem to infer that synchronous calls and asynchronous calls might be handled differently. Should we expect to be able to access the client-principal that was assigned to an appserver session during a synchronous call when we are executing an asynchronous request on the same connection (the same SERVER handle from the client perspective)? Or must we code to specifically assign a client-principal to the REQUEST-INFO on the client-side for every asynchronous call we make, even if the client-principal object to use and the server handle are the same on every call? Thanks for any advice, Mark Opfer DMSi Software

Posted by lecuyer on 25-Jun-2015 10:57

This issue was caused by a bug in the ABL client, and was fixed in OE11.6 in early June.  The fix should be included in the recent ESAP drop.

All Replies

Posted by Michael Jacobs on 20-Apr-2015 15:44

Hi Mark,

The functionality should work as you expect.   But obviously something is not happening correctly.   If I understand the process correctly:

1) The client connects to the AppServer state-free

2) The client runs a synchronous request [to login]

3) The server creates, seals, and returns a Client-Princpal via the SESSION:CURRENT-RESPONSE-INFO:SetClientPrincipal()

4) The client runs a synchronous request and the server obtains a valid Client-Principal via SESSION:CURRENT-REQUEST-INFO:GetClientPrincipal()

5) The client runs an asynchronous request and the server obtains an UNKNOWN from SESSION:CURRENT-REQUEST-INFO:GetClientPrincipal()  {ERROR: expect a valid Client-Principal}

When the client is calling asynchronous requests, are there multiple requests happening at the same time?

Is more than one AppServer serving the one client server connection?

Sorry for the questions, but there are many things happening at the same time internally and this would help us understand where to focus.

Mike Jacobs

Posted by mopfer on 20-Apr-2015 16:26

Hi Mike,
 
  Thanks for the quick response.  It’s always possible we just have a bug in our code somewhere too, so I’m still working that angle as well.
 
  The five steps as you describe them are exactly what I’m seeing.
 
  The client is making multiple connections to the same appserver broker.  The idea is that each connection would have its own client-principal, and the client can be running asynchronous processes on more than one appserver agent/session/connection at a time.
 
  The client can make multiple requests on individual connections, ideally on connections that are not already busy, but the client is limited to a small number of connections so for a case where the requests come more quickly than they can be processed, the requests are stacked up on the connections and run as the connections become available.
 
  I’m seeing the lack of a client-principal on the first asynchronous call, as well as all subsequent calls.  However, if I capture the client-principal from the RESPONSE-INFO after the login call, and then re-assign it to the REQUEST-INFO for the server handle before the next asynchronous call, then the client-principal is available as expected on the appserver.
 
  I’ll try to put together a simple example that has no dependency on our application and send that along.
 
Thanks,
  Mark
 
 
 
 
 
 
[collapse]
From: Michael Jacobs [mailto:bounce-mjacobs@community.progress.com]
Sent: Monday, April 20, 2015 3:45 PM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by Michael Jacobs

Hi Mark,

The functionality should work as you expect.   But obviously something is not happening correctly.   If I understand the process correctly:

1) The client connects to the AppServer state-free

2) The client runs a synchronous request [to login]

3) The server creates, seals, and returns a Client-Princpal via the SESSION:CURRENT-RESPONSE-INFO:SetClientPrincipal()

4) The client runs a synchronous request and the server obtains a valid Client-Principal via SESSION:CURRENT-REQUEST-INFO:GetClientPrincipal()

5) The client runs an asynchronous request and the server obtains an UNKNOWN from SESSION:CURRENT-REQUEST-INFO:GetClientPrincipal()  {ERROR: expect a valid Client-Principal}

When the client is calling asynchronous requests, are there multiple requests happening at the same time?

Is more than one AppServer serving the one client server connection?

Sorry for the questions, but there are many things happening at the same time internally and this would help us understand where to focus.

Mike Jacobs

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by mopfer on 20-Apr-2015 17:14

Here is some code that demonstrates what we see.
 
Cptestclient.p makes two connections to a statefree appserver.  On one connection it calls cptest.p to create a client-principal with a session-id of “One” and on the other it calls cptest2.p to create a client-principal with a session-id of “Two”.  Then it runs cptest3.p asynchronously three times on each server handle and returns the session-id of the client-principal it finds.  The correct session-id is returned on the first call for each server handle, but the client-principal is not found on the other calls to each server handle.
 
There is commented out code in cptestclient.p that can make the process give back the correct result if we capture and re-assign the client-principal for each request, but we would like to avoid having to do that as our real code is more complicated than this example.
 
Also, there is a little commented out code in the cptest.p and cptest2.p where I tried using the session-id from a Progress source instead of session-ids that we made up, just in case that mattered. (It didn’t seem to matter)
 
Please let me know if there is anything else I can add to clarify anything.
 
Thanks,
  Mark
 
 
 
 
[collapse]
From: mopfer [mailto:bounce-mopfer@community.progress.com]
Sent: Monday, April 20, 2015 4:28 PM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by mopfer
Hi Mike,
 
  Thanks for the quick response.  It’s always possible we just have a bug in our code somewhere too, so I’m still working that angle as well.
 
  The five steps as you describe them are exactly what I’m seeing.
 
  The client is making multiple connections to the same appserver broker.  The idea is that each connection would have its own client-principal, and the client can be running asynchronous processes on more than one appserver agent/session/connection at a time.
 
  The client can make multiple requests on individual connections, ideally on connections that are not already busy, but the client is limited to a small number of connections so for a case where the requests come more quickly than they can be processed, the requests are stacked up on the connections and run as the connections become available.
 
  I’m seeing the lack of a client-principal on the first asynchronous call, as well as all subsequent calls.  However, if I capture the client-principal from the RESPONSE-INFO after the login call, and then re-assign it to the REQUEST-INFO for the server handle before the next asynchronous call, then the client-principal is available as expected on the appserver.
 
  I’ll try to put together a simple example that has no dependency on our application and send that along.
 
Thanks,
  Mark
 
 
 
 
 
 
[collapse]
From: Michael Jacobs [mailto:bounce-mjacobs@community.progress.com]
Sent: Monday, April 20, 2015 3:45 PM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by Michael Jacobs

Hi Mark,

The functionality should work as you expect.   But obviously something is not happening correctly.   If I understand the process correctly:

1) The client connects to the AppServer state-free

2) The client runs a synchronous request [to login]

3) The server creates, seals, and returns a Client-Princpal via the SESSION:CURRENT-RESPONSE-INFO:SetClientPrincipal()

4) The client runs a synchronous request and the server obtains a valid Client-Principal via SESSION:CURRENT-REQUEST-INFO:GetClientPrincipal()

5) The client runs an asynchronous request and the server obtains an UNKNOWN from SESSION:CURRENT-REQUEST-INFO:GetClientPrincipal()  {ERROR: expect a valid Client-Principal}

When the client is calling asynchronous requests, are there multiple requests happening at the same time?

Is more than one AppServer serving the one client server connection?

Sorry for the questions, but there are many things happening at the same time internally and this would help us understand where to focus.

Mike Jacobs

Stop receiving emails on this subject.

Flag this post as spam/abuse.

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse][/collapse]

Posted by mopfer on 20-Apr-2015 17:24

I don’t see the files I attempted to attach to the last response, nor do I see an obvious way to attach them to the thread from the Community website.  I’ll try to put the code in this post in a readable format.
 
/* start of cptestclient.p */
 
DEFINE VARIABLE hConnectionToUse  AS HANDLE      NO-UNDO.
DEFINE VARIABLE hConnectionToUse2 AS HANDLE      NO-UNDO.
DEFINE VARIABLE lValid            AS LOGICAL     NO-UNDO.
DEFINE VARIABLE cSessionID        AS CHARACTER   NO-UNDO.
DEFINE VARIABLE hCP               AS HANDLE      NO-UNDO.
DEFINE VARIABLE hCP2              AS HANDLE      NO-UNDO.
 
/* With the code in its initial state, it makes two connections to a
   state-free appserver, then runs cptest.p to create a client-principal
   with a session-id of "One" and cptest2.p to create a client-principal
   of session-id "Two".
  
   cptest3.p gets the current client-principal on the server side, and returns
   the session-ID.  It is run 3 times on each server handle, and is correct on the
   first call but incorrect on the other two calls for both servers.
  
   If the code that is currently commented out is made active, the calls to
   cptest3.p all return the correct session-id.
  
   */
 
 
/* the code in statefreeconnect.p just makes a connection to a state free appserver,
   the output is a server handle */
 
    RUN sys/statefreeconnect.p(
      INPUT  "",
      INPUT  "",
      INPUT  "",
      INPUT  "",
      OUTPUT hConnectionToUse
      ).
 
    /* Create a client-principal on the first connection */
    RUN cptest.p ON SERVER hConnectionToUse
      (OUTPUT lValid).
 
    /*
    hCP = hConnectionToUse:RESPONSE-INFO:GetClientPrincipal().
    hConnectionToUse:REQUEST-INFO:SetClientPrincipal(hCP).
     */
 
    RUN sys/statefreeconnect.p(
      INPUT  "",
      INPUT  "",
      INPUT  "",
      INPUT  "",
      OUTPUT hConnectionToUse2
      ).
 
    /* Create a client-principal on the second connection */
    RUN cptest2.p ON SERVER hConnectionToUse2
      (OUTPUT lValid).
 
    /*
    hCP2 = hConnectionToUse2:RESPONSE-INFO:GetClientPrincipal().
    hConnectionToUse2:REQUEST-INFO:SetClientPrincipal(hCP2).
    */
 
   /* hConnectionToUse:REQUEST-INFO:SetClientPrincipal(hCP). */
    RUN cptest3.p ON SERVER hConnectionToUse ASYNCHRONOUS
        EVENT-PROCEDURE "callBackProcedure"
      (OUTPUT cSessionID).
 
/*   hConnectionToUse2:REQUEST-INFO:SetClientPrincipal(hCP2). */
    RUN cptest3.p ON SERVER hConnectionToUse2 ASYNCHRONOUS
        EVENT-PROCEDURE "callBackProcedure"
      (OUTPUT cSessionID).
 
  /*  hConnectionToUse:REQUEST-INFO:SetClientPrincipal(hCP). */
    RUN cptest3.p ON SERVER hConnectionToUse ASYNCHRONOUS
        EVENT-PROCEDURE "callBackProcedure"
      (OUTPUT cSessionID).
 
   /* hConnectionToUse2:REQUEST-INFO:SetClientPrincipal(hCP2). */
    RUN cptest3.p ON SERVER hConnectionToUse2 ASYNCHRONOUS
        EVENT-PROCEDURE "callBackProcedure"
      (OUTPUT cSessionID).
 
  /*  hConnectionToUse:REQUEST-INFO:SetClientPrincipal(hCP). */
    RUN cptest3.p ON SERVER hConnectionToUse ASYNCHRONOUS
        EVENT-PROCEDURE "callBackProcedure"
      (OUTPUT cSessionID).
 
   /* hConnectionToUse2:REQUEST-INFO:SetClientPrincipal(hCP2). */
    RUN cptest3.p ON SERVER hConnectionToUse2 ASYNCHRONOUS
        EVENT-PROCEDURE "callBackProcedure"
      (OUTPUT cSessionID).
 
 
    DEFINE VARIABLE iCount AS INTEGER     NO-UNDO.
 
    /* give the callbacks an opening to run through */
    DO iCount = 1 TO 6:
   
      PAUSE 1.
      PROCESS EVENTS.
    END.
 
    PROCEDURE callBackProcedure:
 
      DEFINE INPUT PARAMETER pcSessionID AS CHARACTER NO-UNDO.
 
      MESSAGE "sessionID in callBackProcedure = " pcSessionID VIEW-AS ALERT-BOX.
 
    END.
 
/* end of cptestclient.p */
 
/* start of cptest.p */
DEFINE OUTPUT PARAMETER oplValid AS LOGICAL NO-UNDO.
 
DEFINE VARIABLE ipcUserID        AS CHARACTER   NO-UNDO INIT "UserID".
DEFINE VARIABLE ipcPassword      AS CHARACTER   NO-UNDO INIT "Password".
DEFINE VARIABLE opcSessionID     AS CHARACTER   NO-UNDO.
DEFINE VARIABLE hClientPrincipal AS HANDLE      NO-UNDO.
 
opcSessionID = "One".
 
CREATE CLIENT-PRINCIPAL hClientPrincipal.
hClientPrincipal:INITIALIZE (ipcUserID,opcSessionID,?,ipcPassword).
/* hClientPrincipal:INITIALIZE (ipcUserID,SESSION:CURRENT-REQUEST-INFO:clientContextID,?,ipcPassword).*/
 
/* SEAL is not needed to be specifically done, the SET-DB-CLIENT seals the CP and
   sets its login-state to "LOGIN" */
oplValid = SET-DB-CLIENT(hClientPrincipal).
 
/* attach the client-principal to the current client session */
SESSION:CURRENT-RESPONSE-INFO:SetClientPrincipal(hClientPrincipal).
 
/* end of cptest.p */
 
/* start of cptest2.p */
DEFINE OUTPUT PARAMETER oplValid AS LOGICAL NO-UNDO.
 
DEFINE VARIABLE ipcUserID        AS CHARACTER   NO-UNDO INIT "UserID".
DEFINE VARIABLE ipcPassword      AS CHARACTER   NO-UNDO INIT "Password".
DEFINE VARIABLE opcSessionID     AS CHARACTER   NO-UNDO.
DEFINE VARIABLE hClientPrincipal AS HANDLE      NO-UNDO.
 
opcSessionID = "Two".
 
CREATE CLIENT-PRINCIPAL hClientPrincipal.
hClientPrincipal:INITIALIZE (ipcUserID,opcSessionID,?,ipcPassword).
/* hClientPrincipal:INITIALIZE (ipcUserID,SESSION:CURRENT-REQUEST-INFO:clientContextID,?,ipcPassword).*/
 
/* SEAL is not needed to be specifically done, the SET-DB-CLIENT seals the CP and
   sets its login-state to "LOGIN" */
oplValid = SET-DB-CLIENT(hClientPrincipal).
 
/* attach the client-principal to the current client session */
SESSION:CURRENT-RESPONSE-INFO:SetClientPrincipal(hClientPrincipal).
 
/* end of cptest 2.p */
 
/* Start of cptest3.p */
  DEFINE OUTPUT PARAMETER opcSessionID AS CHARACTER   NO-UNDO.
 
  DEFINE VARIABLE reqObj             AS Progress.Lang.OERequestInfo NO-UNDO.
  DEFINE VARIABLE hCP                AS HANDLE      NO-UNDO.
 
 
  reqObj = SESSION:CURRENT-REQUEST-INFO.
 
  hCP = reqObj:GetClientPrincipal().
 
  IF VALID-HANDLE(hCP) THEN
    opcSessionID = hCP:SESSION-ID.
  ELSE
    opcSessionID = "Not Valid".
 
/* end of cptest3.p */
 
 
 
[collapse]
From: mopfer [mailto:bounce-mopfer@community.progress.com]
Sent: Monday, April 20, 2015 5:15 PM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by mopfer
Here is some code that demonstrates what we see.
 
Cptestclient.p makes two connections to a statefree appserver.  On one connection it calls cptest.p to create a client-principal with a session-id of “One” and on the other it calls cptest2.p to create a client-principal with a session-id of “Two”.  Then it runs cptest3.p asynchronously three times on each server handle and returns the session-id of the client-principal it finds.  The correct session-id is returned on the first call for each server handle, but the client-principal is not found on the other calls to each server handle.
 
There is commented out code in cptestclient.p that can make the process give back the correct result if we capture and re-assign the client-principal for each request, but we would like to avoid having to do that as our real code is more complicated than this example.
 
Also, there is a little commented out code in the cptest.p and cptest2.p where I tried using the session-id from a Progress source instead of session-ids that we made up, just in case that mattered. (It didn’t seem to matter)
 
Please let me know if there is anything else I can add to clarify anything.
 
Thanks,
  Mark
 
 
 
 
[collapse]
From: mopfer [mailto:bounce-mopfer@community.progress.com]
Sent: Monday, April 20, 2015 4:28 PM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by mopfer
Hi Mike,
 
  Thanks for the quick response.  It’s always possible we just have a bug in our code somewhere too, so I’m still working that angle as well.
 
  The five steps as you describe them are exactly what I’m seeing.
 
  The client is making multiple connections to the same appserver broker.  The idea is that each connection would have its own client-principal, and the client can be running asynchronous processes on more than one appserver agent/session/connection at a time.
 
  The client can make multiple requests on individual connections, ideally on connections that are not already busy, but the client is limited to a small number of connections so for a case where the requests come more quickly than they can be processed, the requests are stacked up on the connections and run as the connections become available.
 
  I’m seeing the lack of a client-principal on the first asynchronous call, as well as all subsequent calls.  However, if I capture the client-principal from the RESPONSE-INFO after the login call, and then re-assign it to the REQUEST-INFO for the server handle before the next asynchronous call, then the client-principal is available as expected on the appserver.
 
  I’ll try to put together a simple example that has no dependency on our application and send that along.
 
Thanks,
  Mark
 
 
 
 
 
 
[collapse]
From: Michael Jacobs [mailto:bounce-mjacobs@community.progress.com]
Sent: Monday, April 20, 2015 3:45 PM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by Michael Jacobs

Hi Mark,

The functionality should work as you expect.   But obviously something is not happening correctly.   If I understand the process correctly:

1) The client connects to the AppServer state-free

2) The client runs a synchronous request [to login]

3) The server creates, seals, and returns a Client-Princpal via the SESSION:CURRENT-RESPONSE-INFO:SetClientPrincipal()

4) The client runs a synchronous request and the server obtains a valid Client-Principal via SESSION:CURRENT-REQUEST-INFO:GetClientPrincipal()

5) The client runs an asynchronous request and the server obtains an UNKNOWN from SESSION:CURRENT-REQUEST-INFO:GetClientPrincipal()  {ERROR: expect a valid Client-Principal}

When the client is calling asynchronous requests, are there multiple requests happening at the same time?

Is more than one AppServer serving the one client server connection?

Sorry for the questions, but there are many things happening at the same time internally and this would help us understand where to focus.

Mike Jacobs

Stop receiving emails on this subject.

Flag this post as spam/abuse.

Stop receiving emails on this subject.

Flag this post as spam/abuse.

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse][/collapse][/collapse]

Posted by Michael Jacobs on 21-Apr-2015 04:48

Hi Mark,

Attaching files, I find, is a bit obscure.   Click on the "Use rich formatting" link in the reply box.   This will take you to a new page with three tabs "compose", "options", "<I forget>".   In the "options" tab I can add files.  At the bottom is a simple RTF editor box in which I can enter the text reply.  

Slightly off topic - but why manually manage multiple connections to a state-free appserver in your ABL code rather than use a single appserver connection and let the connection manage multiple physical appserver connections and simultaneous asynchronous request executions?

Anyway... we'll look at the code, see if we can see the same behavior, and get back to you.

Have a good day,

Mike Jacobs

Posted by Stefan Drissen on 21-Apr-2015 05:53

[quote user="Michael Jacobs"]

Slightly off topic - but why manually manage multiple connections to a state-free appserver in your ABL code rather than use a single appserver connection and let the connection manage multiple physical appserver connections and simultaneous asynchronous request executions?

[/quote]

I am not the OP, but we have two reasons for managing multiple connections from the client:

1. synchronous and asynchronous calls cannot be mixed on the fly

2. one asynchronous connection will handle requests in queued order - if the user decides to start something else it should not wait in the queue of the application that is still handling async requests for the previous application that is still busy.

Regards,

Stefan

Posted by mopfer on 21-Apr-2015 07:17

Hi Mike,

 

  Thanks for the information about attaching files.  

 

  Our main reason for wanting to have multiple connections is that the processes that run asynchronously sometimes change properties in the application's session context while they are running, and we don't want the various processes to be sharing the same application context while they are running.  So the idea is that each connection has its own context. 

 

With that said, it may be that we don't really want to have more than one process running asynchronously on a particular connection on a state-free appserver.  We've been stacking asynchronous calls on a state-reset appserver for years, trusting them to run in the order that we put them on the stack, but maybe state-free asynchronous calls don't work that way. 

 

If I make three asynchronous calls to a state-free appserver connection, will they get run one after another, or will each request be handed to a separate appserver session immediately and all three will be running at the same time?  I may have to adjust what I'm trying to do.

 

Thanks,

Mark


[collapse]
From: Michael Jacobs <bounce-mjacobs@community.progress.com>
Sent: Tuesday, April 21, 2015 4:49 AM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by Michael Jacobs

Hi Mark,

Attaching files, I find, is a bit obscure.   Click on the "Use rich formatting" link in the reply box.   This will take you to a new page with three tabs "compose", "options", "<I forget>".   In the "options" tab I can add files.  At the bottom is a simple RTF editor box in which I can enter the text reply.  

Slightly off topic - but why manually manage multiple connections to a state-free appserver in your ABL code rather than use a single appserver connection and let the connection manage multiple physical appserver connections and simultaneous asynchronous request executions?

Anyway... we'll look at the code, see if we can see the same behavior, and get back to you.

Have a good day,

Mike Jacobs

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Michael Jacobs on 21-Apr-2015 07:29

My thanks to both Mark and Stefan for adding some background for using multiple connections.  I'll be adding these to my store of use cases.

Mike J.

Posted by lecuyer on 21-Apr-2015 10:46

There is a fundamental difference in the way that asynchronous requests from an ABL client are handled  for session-managed (i.e. state-reset, state-aware, stateless) appservers than for session-free (i.e. state-free) appservers.

In session-managed mode, when a client application connects a server handle, a single physical connection is made between the client and appserver, and all requests from that server handle are run on that connection.  Only one request can be active on that request at a time.  When requests are run asynchronously, they are run serially on that single connection in the order that the RUN statements were executed.  The developer is assured of a FIFO behavior and can depend on the order the requests will run.

In session-free mode, when a client application connects a server handle, a pool of physical connections is established between the client and appserver.  This pool can contain multiple physical connections to one or more appservers (when using load balancing).  As asynch requests are run, connections are temporarily reserved from the connection pool and used for the duration of the request; when the request is over, the connection goes back into the pool, and can be used for a different request.  If an asynch request is made and there are no available connections in the pool (i.e. all existing connections are currently being used by running asynch requests) a new connection is established to run the request.  Once the request is over, that connection is returned to the pool.  In this way, the pool can grow in size, depending on the maximum number of concurrent asynch requests run on that server handle.

The initial size and upper size limit of this pool can be determined by optional connection parameters specified in the first parameter to hSrv:CONNECT().  The default behavior is to establish one connection when the hSrv:CONNECT() is run, and create an unrestricted number of additional connections "on demand".

The key thing to note from this behavior is that, when multiple asynch requests are run, they can each run immediately on separate connections, in parallel (provided that sufficient connections can be reserved and/or created).  That is, they are NOT serialized on a single connection.  As a result, the order that they execute cannot be predicted.  Also, depending on how long each request runs, the responses can return in a different order than they were executed.

Posted by mopfer on 21-Apr-2015 14:00

Lecuyer -
  
  Thank you for the thorough explanation of how the timing works with asynchronous calls to a state-free appserver.  That makes sense,  and I will need to make an adjustment to part of what I’m trying to accomplish.
 
  I think that I do still want to know if the CURRENT-REQUEST-INFO contents in the appserver session should be different on the second asynchronous call on a particular connection than they were on the first one though.  Even with my better understanding of the timing, I think there are cases where running multiple asynchronous requests on the same connection is something we will want to do, if we can access the same session context information for all of the requests.
 
Thanks,
  Mark
 
[collapse]
From: lecuyer [mailto:bounce-lecuyer@community.progress.com]
Sent: Tuesday, April 21, 2015 10:47 AM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by lecuyer

There is a fundamental difference in the way that asynchronous requests from an ABL client are handled  for session-managed (i.e. state-reset, state-aware, stateless) appservers than for session-free (i.e. state-free) appservers.

In session-managed mode, when a client application connects a server handle, a single physical connection is made between the client and appserver, and all requests from that server handle are run on that connection.  Only one request can be active on that request at a time.  When requests are run asynchronously, they are run serially on that single connection in the order that the RUN statements were executed.  The developer is assured of a FIFO behavior and can depend on the order the requests will run.

In session-free mode, when a client application connects a server handle, a pool of physical connections is established between the client and appserver.  This pool can contain multiple physical connections to one or more appservers (when using load balancing).  As asynch requests are run, connections are temporarily reserved from the connection pool and used for the duration of the request; when the request is over, the connection goes back into the pool, and can be used for a different request.  If an asynch request is made and there are no available connections in the pool (i.e. all existing connections are currently being used by running asynch requests) a new connection is established to run the request.  Once the request is over, that connection is returned to the pool.  In this way, the pool can grow in size, depending on the maximum number of concurrent asynch requests run on that server handle.

The initial size and upper size limit of this pool can be determined by optional connection parameters specified in the first parameter to hSrv:CONNECT().  The default behavior is to establish one connection when the hSrv:CONNECT() is run, and create an unrestricted number of additional connections "on demand".

The key thing to note from this behavior is that, when multiple asynch requests are run, they can each run immediately on separate connections, in parallel (provided that sufficient connections can be reserved and/or created).  That is, they are NOT serialized on a single connection.  As a result, the order that they execute cannot be predicted.  Also, depending on how long each request runs, the responses can return in a different order than they were executed.

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Michael Jacobs on 22-Apr-2015 06:27

Hi Mark,

I took your sample code and ran it in a state-free AppServer this morning.

   It did not work correctly - at least not to my expectations.

Adding some 'message' debug statements I've found that the first async call to a server handle passes correctly the ClientContextId and ClientPrincipal to the AppServer that was received from the first sync call.   Thereafter, the 2nd, 3rd, etc async calls to the AppServer passed unknown for both the ClientContextId and the ClientPrincipal.  It is like the first async call clears the server handle's ClientContextId and ClientPrincipal.  

I'll next consult Peter and take a closer look to see what options are available.   I'll be back...

Mike J.

Posted by Darren Parr on 25-Jun-2015 07:14

Did this get solved? Ive only just come across this thread but am having this exact same issue, only with PAS. Im connecting to a session-free appserver for async requests only and using a state-reset appserver for sync requests. We only use our async process for fetching data for the user interface so it works well.

On my first request I create a context record using clientcontextid for session data etc. The contextid is perfectly returned and valid. An activate procedure shows the contextid as valid on the first async request. As soon as I launch the second async request (the first request is completed at this time) it has ? as the value for contextid and is unable to retrieve the context data.

Any ideas?

-Darren

Posted by mopfer on 25-Jun-2015 10:56

Hi Darren,
 
We haven’t heard anything further on the topic from Progress yet.  We are still using 11.4 so I don’t know if anything has changed in the latest OpenEdge release.
 
As we got farther into our project we found that we really do have cases where we want the same session context maintained from one asynch call to the next on the same state-free connection, so we are putting code in to manage keeping track of the handle to the client-principal we want to use for each connection and then re-attaching the client-principal to the connection in between calls with the connection’s REQUEST-INFO:SetClientPrincipal() method.  We’re also having to set REQUEST-INFO:ClientContextID to match the client-principal’s session ID, as that does not appear to be done automatically as part of the SetClientPrincipal() method. 
 
 
Mark
 
 
[collapse]
From: Darren Parr [mailto:bounce-DarrenP@community.progress.com]
Sent: Thursday, June 25, 2015 7:16 AM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by Darren Parr

Did this get solved? Ive only just come across this thread but am having this exact same issue, only with PAS. Im connecting to a session-free appserver for async requests only and using a state-reset appserver for sync requests. We only use our async process for fetching data for the user interface so it works well.

On my first request I create a context record using clientcontextid for session data etc. The contextid is perfectly returned and valid. An activate procedure shows the contextid as valid on the first async request. As soon as I launch the second async request (the first request is completed at this time) it has ? as the value for contextid and is unable to retrieve the context data.

Any ideas?

-Darren

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by lecuyer on 25-Jun-2015 10:57

This issue was caused by a bug in the ABL client, and was fixed in OE11.6 in early June.  The fix should be included in the recent ESAP drop.

Posted by mopfer on 25-Jun-2015 10:59

Thanks for the fix and the news.
 
Mark
 
[collapse]
From: lecuyer [mailto:bounce-lecuyer@community.progress.com]
Sent: Thursday, June 25, 2015 10:58 AM
To: TU.OE.General@community.progress.com
Subject: RE: [Technical Users - OE General] Is CURRENT-REQUEST-INFO handled differently for asynchronous calls than synchronous calls?
 
Reply by lecuyer

This issue was caused by a bug in the ABL client, and was fixed in OE11.6 in early June.  The fix should be included in the recent ESAP drop.

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Darren Parr on 25-Jun-2015 16:03

I was about to say it was still broken in 11.5.1. I've gotten around it by resetting clientcontextid and the clientprincipal on return. I'll have a look at 11.6 when it comes out. I don't believe 11.6 is due until the fall.

Any idea if this will make its was to 11.5.2 and do we have a date for this SP.

-Darren

This thread is closed