-
Session Pools or Session Objects
At Euromnis 2018, some of us started looking at how session pools are used by row and list variables.
The Omnis manuals offer advice to define a row variable from a sql class and then assign a session object to it. That session object is held as an instance variable or task variable within the remote task.
e.g.Do SessObj.$logon(hostname,username,password)
Do iResultsList.$definefromsqlclass('T_authors')
Do iResultsList.$sessionobject.$assign(SessObj)
Every row and list variable can be assigned the same session object. Once assigned, the row.list variable will have a property called $statementobject which will be used by the built in methods ($select, $insert, etc) or can be used by the programmer within their table class methods.
However, when building a web based application, we often look to use session pools, so that we don’t have to create a new connection to the database for each user. It seems more efficient to have a pool of sessions from which we can draw a session object as and when required. Thus, providing you take a session object from the pool when it is required and deallocate it after use, the number of connections to your database (N) can be less than the number of users concurrently running your application (U). (U > N)
Beware
Now Omnis provides a way of assigning a session from the session pool to a row or list variable, but I want to show how this can have the opposite effect of reducing connections to the database:Do iResultsList.$definefromsqlclass('T_authors')
Do iResultsList.$sessionobject.$assign($sessionpools.poolone.$new())
This way of allocating a unique session object from the session pool to each row or list variable means that a session object will be ‘in use’ for as long as each variable is in existence. Therefore, if you build 3, 4, 5 or more rows and lists and display them on a remote form, your application will be tying up that many sessions.
i.e. Rather than reducing the number of session connections to your database, you will probably increase it. (N > U.)
This can be proved by monitoring the value of the $inuse property of your session pool and opening a remote form that has 2 or more lists or row variables on it, defined in this way.
There are two potential workarounds I can think of:
1) Hand write every query you wish to perform within your code or within table classes. Every method will take a session object from the session pool, hold it in a local variable, and return it to the pool at the end. Do not use any built in methods of schema/table classes because you cannot use the $sessionobject.$assign() method that makes these operable.
e.g. $select methodDo $ctask.$getSessionObj() Returns loSessionObj
Do loSessionObj.$newstatement() Returns loStatementObj
Begin statement
Sta: {select * from Authors}
End statement
Do loStatementObj.$prepare()
Do loStatementObj.$execute()
Do loStatementObj.$fetch(ivLst,kFetchAll)
2) Build your code in such a way that all lists and row variables are constructed as local variables and returned to the method requiring them.
e.g.Do lvLst.$definefromsqlclass('tAuthors')
Do lvLst.$select()
Do ivLst.$copy(lvLst)
Do ivLst.$merge(lvLst,kTrue,kFalse,kTrue)
This way, the local variable lvLst only exists for a short time, during which it is given a session object from the pool. However, once the select operation has been performed, the local variable is thrown away, the session object returns to the pool but we keep a copy of the data in the instance variable.
Has anyone else looked into this, tested different scenarios, and decided on a preferred solution?
Sorry, there were no replies found.
Log in to reply.