BTW, since you have a framework product, you already have Memory_Services which is a convenient wrapper around the SRP_HashTable. You already have code using this so you can use that to guide you if you want to consider using it.
The Why - These are to be used if you want to set an expiration date to the data stored in memory.
The When - For instance, perhaps you want to store a list of keys in memory for quick access later. However, if these keys are dynamic then you might not want these keys to be in memory forever. This gives you the ability to define how long the keys can be cached before the information is cleared and your logic will know to rebuild the keys.
Look at the GetDatabaseItems service in HTTP_Resource_Services. You'll see that it calls the GetValue service first to get the HAL data. However, the NotExpired flag is set to True$ which means we want to make sure this data is not too stale. The ExpirationDuration is set to 1 (i.e., 1 second), so if the data in memory is older than 1 second then this service returns an empty string. This empty string tells the rest of the GetDatabaseItems service that it needs to run its normal logic (which then updates the memory cache).
Hi Don- Great to be on board your forum. I need to find a good picture of me :)
I may be over engineering this but...... #1) In my O4W entry point off the web (home page or otherwise) - I do something like: Handle = SRP_HashTable("Create")
#2) Then I need to remember that handle during the entire user session - so I need to pass it as a parameter in all my subroutine and function calls that need stuff in SRP_HashTable ?
#3) How many Handles (i.e. users) can I have ?
#4) The handle increments by some factor for each new user the shows up - but at only seven digits - it does not appear to be a GUID - so I guess there is a remote possibility a duplicate could occur ?
#5) Once a user logs off I do a SRP_HashTable("Release", Handle) But what if they just close the browser - they never really logged off - they just went away.
#6) Is there a way to check to see when a handle was last used ?
#7) Or as part of "Overnite/End of Cycle Processing" - is there a way to release ALL handles?
#1) Yes. That creates an empty hash table. #2) Yes. A global common can be a useful way of doing this. #3) As many as can fit in memory. It all depends on how much stuff you put into each hash table. #4) The handle is an abstract entity, but under the hood, it is essentially a memory pointer. Handles will never collide. #5) If the handle is meant to last the life of the application, then you don't need to do a RELEASE. Everything will be released. As for users that don't log off, I suppose you'll have to do some sleuthing to see if they are inactive, then do a RELEASE #6) No. You'll have to keep track of that yourself. #7) You can loop through all handles and RELEASE each one, but there is nothing currently built in to do that for you.
Kevin beat me to the punch with some answers. His answers are similar to what I would have written so I'll focus on a tangential issue that I think will impact your approach to this.
After reviewing your questions I have a better idea of what you are trying to do. I need to set your expectations with this. Using an in-memory hashtable (whether ours or Rev's) cannot be shared across other engines. I see you are trying to create a global pool of memory that is session specific. In the Rev forum I was using session to refer to any round-trip request/response. You are using session to refer to any active engagement by the user in your web application up and until they log off or the system times out.
Your approach to session management won't work the way you want it to because you have no control over which engine will be used to handle a given request. That is to say, if a user's session begins with Engine1 and stores data in the SRP HashTable, then a subsequent connection for this same session could be handled by Engine2 which will not have access to the same SRP HashTable. Each engine has its own SRP HashTable. This is the nature of the beast.
Thus, storing data in a database is the only way to truly have access to all related data for the same session. The popular cloud-centric databases (like Couchbase) solve this problem using technology like MemCached, but that is taking things to a much higher level.
Tx Kevin- within the handle, I will maintain a var "HANDLELASTUSED" ? Is there a way to get a list of all the handles in srp_hashtable ? (would make cleanup a lot easier ) tx bri
Hi Kevin and Don - Yes - I think I am going full circle on this where I either need to use common or pass vars. And the common may not work either in O4W - as the code below does not remember what abc1@ is defined as when O4W cycles.
As soon as possible, give up the idea of sharing variables between sessions. This just won't work. The easiest way to look at this is as if you had two copies of OI running and ask yourself, "is it possible for my first OI to share data with my second OI?" The answer is, "Yes, but only through a persistent storage solution."
I'll take this time to note that this is why web applications aren't meant to be stateful. When you impose session management in a web application, you are layering a stateful design on top of what is meant to be stateless. This is a natural approach when we as desktop application developers attempt to create web applications to work the same way. I'm not saying it is impossible, but it becomes more and more a square peg in a round hole.
Hi Don and Kevin - Points well taken and to prove them TRUE, I decided to spin a little more and use Bryan's UserFields@ common in O4W_CUMMUTER common and put the Handle in that field. All works perfect until I open up an additional browser or two - at which time the Handles don't go way but "get confused" and sometimes I end up with the wrong handle SRP_HASHTABLE data. So the only way it works - as I know anyway - is to save my MYVARS and MYVARVALUES in a file using O4WSessionID% as the RecID. thanks again guys for the ideas AND explanation as to what is going on in the background.
Comments
I was wanting to know if Value can be @record
I don't quite get the use of NotExpired and ExpirationDuration here.
Memory_Services('GetValue', KeyID, NotExpired, ExpirationDuration)
Can you explain why & when it should be used.
The When - For instance, perhaps you want to store a list of keys in memory for quick access later. However, if these keys are dynamic then you might not want these keys to be in memory forever. This gives you the ability to define how long the keys can be cached before the information is cleared and your logic will know to rebuild the keys.
Look at the GetDatabaseItems service in HTTP_Resource_Services. You'll see that it calls the GetValue service first to get the HAL data. However, the NotExpired flag is set to True$ which means we want to make sure this data is not too stale. The ExpirationDuration is set to 1 (i.e., 1 second), so if the data in memory is older than 1 second then this service returns an empty string. This empty string tells the rest of the GetDatabaseItems service that it needs to run its normal logic (which then updates the memory cache).
Great to be on board your forum.
I need to find a good picture of me :)
I may be over engineering this but......
#1)
In my O4W entry point off the web (home page or otherwise) - I do something like:
Handle = SRP_HashTable("Create")
#2)
Then I need to remember that handle during the entire user session - so I need to pass it as a parameter in all my subroutine and function calls that need stuff in SRP_HashTable ?
#3)
How many Handles (i.e. users) can I have ?
#4)
The handle increments by some factor for each new user the shows up - but at only seven digits - it does not appear to be a GUID - so I guess there is a remote possibility a duplicate could occur ?
#5)
Once a user logs off I do a SRP_HashTable("Release", Handle)
But what if they just close the browser - they never really logged off - they just went away.
#6)
Is there a way to check to see when a handle was last used ?
#7)
Or as part of "Overnite/End of Cycle Processing" - is there a way to release ALL handles?
Tx.
Bri
#2) Yes. A global common can be a useful way of doing this.
#3) As many as can fit in memory. It all depends on how much stuff you put into each hash table.
#4) The handle is an abstract entity, but under the hood, it is essentially a memory pointer. Handles will never collide.
#5) If the handle is meant to last the life of the application, then you don't need to do a RELEASE. Everything will be released. As for users that don't log off, I suppose you'll have to do some sleuthing to see if they are inactive, then do a RELEASE
#6) No. You'll have to keep track of that yourself.
#7) You can loop through all handles and RELEASE each one, but there is nothing currently built in to do that for you.
Kevin beat me to the punch with some answers. His answers are similar to what I would have written so I'll focus on a tangential issue that I think will impact your approach to this.
After reviewing your questions I have a better idea of what you are trying to do. I need to set your expectations with this. Using an in-memory hashtable (whether ours or Rev's) cannot be shared across other engines. I see you are trying to create a global pool of memory that is session specific. In the Rev forum I was using session to refer to any round-trip request/response. You are using session to refer to any active engagement by the user in your web application up and until they log off or the system times out.
Your approach to session management won't work the way you want it to because you have no control over which engine will be used to handle a given request. That is to say, if a user's session begins with Engine1 and stores data in the SRP HashTable, then a subsequent connection for this same session could be handled by Engine2 which will not have access to the same SRP HashTable. Each engine has its own SRP HashTable. This is the nature of the beast.
Thus, storing data in a database is the only way to truly have access to all related data for the same session. The popular cloud-centric databases (like Couchbase) solve this problem using technology like MemCached, but that is taking things to a much higher level.
within the handle, I will maintain a var "HANDLELASTUSED" ?
Is there a way to get a list of all the handles in srp_hashtable ? (would make cleanup a lot easier )
tx
bri
That being said, it seems like you should give Don's post a read above as there are limitations to what this can do for you from a cloud perspective.
Yes - I think I am going full circle on this where I either need to use common or pass vars.
And the common may not work either in O4W - as the code below does not remember what abc1@ is defined as when O4W cycles.
Subroutine O4W_Main1Form(CtlEntId, Event, Request)
$Insert O4WEquates
debug
Common /MyCommon1/ abc1@
abc1@ = "asdfasdfsd"
.......
return
As soon as possible, give up the idea of sharing variables between sessions. This just won't work. The easiest way to look at this is as if you had two copies of OI running and ask yourself, "is it possible for my first OI to share data with my second OI?" The answer is, "Yes, but only through a persistent storage solution."
I'll take this time to note that this is why web applications aren't meant to be stateful. When you impose session management in a web application, you are layering a stateful design on top of what is meant to be stateless. This is a natural approach when we as desktop application developers attempt to create web applications to work the same way. I'm not saying it is impossible, but it becomes more and more a square peg in a round hole.
Points well taken and to prove them TRUE,
I decided to spin a little more and use Bryan's UserFields@ common in O4W_CUMMUTER common and put the Handle in that field. All works perfect until I open up an additional browser or two - at which time the Handles don't go way but "get confused" and sometimes I end up with the wrong handle SRP_HASHTABLE data.
So the only way it works - as I know anyway - is to save my MYVARS and MYVARVALUES in a file using O4WSessionID% as the RecID.
thanks again guys for the ideas AND explanation as to what is going on in the background.
Bri