Quantcast
Channel: SCN : All Content - SAP Gateway
Viewing all articles
Browse latest Browse all 2823

Closing session of Soft State OData service

$
0
0

 

Hello,

I would like to share the idea how you can manage or kill the session of your Soft State OData Service.

For more information regarding Soft State Support for OData Services look here: http://help.sap.com/saphelp_gateway20sp09/helpdata/en/f6/5f8e5318e83d27e10000000a44538d/content.htm

and here:

http://scn.sap.com/docs/DOC-58760.

As discussed, you will probably implement Stateful or Soft State OData in the applications, where you can gain a lot from this. This can be any application, which is continuously working with considerable amount of data. Typical example would be taking an order with many items and complex pricing or very complex and flexible reports, which are working with the data stored in the memory. By default, your session will timeout according to the settings you set up for your service in the transaction SICF.

Now it comes a tricky question, how big should this timeout be? 1 hour or maybe 1 second? You’llsay, depends on the application. Yes, true. But, isn’t it better to make it manageable?

Imagine in your order taking application you have simply forgotten, or maybe it is just not possible, to release the memory after the order is finished. Your memory will be leaking, right? Even closing the browser will not help. You will see more and more pending sessions in SM04 (AL08) transaction, consuming more and more memory of your system.

SM04.jpg

Below I will describe one way how you can close the Soft State OData session programmatically.

First, what you need to know that it is possible to kill this session right from transaction SM04. Therefore, we will simulate exactly this step.

You can get the session information using CL_SERVER_INFO => GET_SESSION_LIST. After that, you will need to call the function TH_DELETE_USER to kill this session. Let’s to a simple function, where the input parameter would be a path to the OData service.

functionzdmsh_delete_odata_session.
 
*"----------------------------------------------------------------------
 
*"*"Local Interface:
 
*"  IMPORTING
 
*"     VALUE(IV_PATH) TYPE  STRING
 
*"----------------------------------------------------------------------
 
   
include: tskhincl.
 
   
data: server_info  type ref to cl_server_info.
 
   
data(lv_path) = iv_path.
   
translatelv_pathto upper case.
 
   
try.
       
createobject server_info.
 
       
data(session_list) = server_info->get_session_list( with_application_info = 1
                                                            tenant
= sy-mandt ).
 
       
loop at session_list assigning field-symbol(<fs_session_info>)
         
where user_name  = sy-uname
           
and logon_type= 3
           
and logon_sub_type= 4
           
and act_program= 'SAPMHTTP'.
 
         
translate<fs_session_info>-application_info to upper case.
 
         
if<fs_session_info>-application_infocslv_path.
 
           
call function 'TH_DELETE_USER'
             
exporting
                user           
= sy-uname
               
client          = sy-mandt
                tid            
= <fs_session_info>-logon_hdl
                logon_id       
= <fs_session_info>-logon_id
             
exceptions
                authority_error
= 1
               
others          = 2.
           
ifsy-subrc<> 0.
             
continue.
           
endif.
         
endif.
       
endloop.
 
     
catchcx_root.
       
exit.
   
endtry.
 
 
endfunction.

 

Then you need to call this function somehow. In my case, the function TH_DELETE_USER does not work if I call it from the same session, which I am trying to kill. Don’t know why, but it was the case. Therefore, you need to call it from another session, which can be another OData service or simply a web-rfc function.

I used the last option. For more information regarding web-rfc, see here: http://scn.sap.com/community/netweaver-as/blog/2012/08/07/webrfc--simply-calling-an-rfc-from-javascript

So, the function looks very simple.

functionzdmsh_delete_user_webrfc.
 
*"----------------------------------------------------------------------
 
*"*"Local Interface:
 
*"  TABLES
 
*"      QUERY_STRING STRUCTURE  W3QUERY
 
*"      HTML STRUCTURE  W3HTML
 
*"      MIME STRUCTURE  W3MIME
 
*"  CHANGING
 
*"     REFERENCE(CONTENT_TYPE) TYPE  W3PARAM-CONT_TYPE DEFAULT
 
*"       'application/json'
 
*"     REFERENCE(CONTENT_LENGTH) TYPE  W3PARAM-CONT_LEN
 
*"     REFERENCE(RETURN_CODE) TYPE  W3PARAM-RET_CODE
 
*"----------------------------------------------------------------------
 
   
data: path type string.
   
data: rctype numc5.
 
   
sortquery_stringdescending.
   
read table query_stringwith key name = '_OdataSrv'.
 
    path
= query_string-value.
 
   
call function 'ZDMSH_DELETE_ODATA_SESSION'
     
exporting
        iv_path
= path
     
importing
        rc     
= rc.
 
   
data: htmldoclike line of html.
 
   
concatenate'{"results": [ {"key": "path", "value": "' path '"},'
                            
' {"key": "error", "value": "' rc '"}]}' into htmldoc-line.
 
   
inserthtmldocinto table html.
 
 
endfunction.

 

After that, you just need to call it via the URL: http://<server>:<port>//sap/bc/webrfc?_FUNCTION=<FUNC_NAME>&_OdataSrv=<SERVICE_PATH>

At last, you need to create a JavaScript function and attach it to proper event (e.g. window.onbeforeunload / window.addEventListener) or a button. From there you can call the above URL, for instance as AJAX request.

Hope it was useful.

If you find any mistake or a bug, or have a better solution, do not hesitate to comment it cout.

BR, Dima

 

 


Viewing all articles
Browse latest Browse all 2823

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>