Session Management in TWebModule - delphi

I am using a TWebModule with Apache. If I understand correctly Apache will spawn another instance of my TWebModule object if all previous created objects are busy processing requests. Is this correct?
I have created my own SessionObject and have created a TStringList to store them. The StringList is created in the initialization section at the bottom of my source code file holding the TWebModule object. I am finding initialization can be called multiple times (presumably when Apache has to spawn another process).
Is there a way I could have a global "Sessions" TStringlist to hold all of my session objects? Or is the "Safe", proper method to store session information in a database and retrieve it based on a cookie for each request?
The reason I want this is to cut down on database access and instead hold session information in memory.
Thanks.

As Stijn suggested, using a separate storage to hold the session data really is the best way to go. Even better is to try to write your application so that the web browser contains the state inherently in the design. This will greatly increase the ability to scale your application into the thousands or tens of thousands of concurrent users with much less hardware.
Intraweb is a great option, but suffers from the scale issue in the sense that more concurrent users, even IDLE users, require more hardware to support. It is far better to design from the onset a method of your server running as internally stateless as possible. Of course if you have a fixed number of users and don't expect any growth, then this is less of an issue.

That's odd. If initialization sections get called more than once, it might be because the DLL is loaded in separate process spaces. One option I can think up is to check if the "Sessions" object already exists when you create it on initialization. If the DLL really is loaded in separate processes, this will not help, and then I suggest writing a central Session storage process and use inter-process-communication from within your TWebModule (there are a few methods: messages, named pipes, COM...)

Intraweb in application mode really handles session management and database access very smoothly, and scales well. I've commented on it previously. While this doesn't directly answer the question you asked, when I faced the same issues Intraweb solved them for me.

Related

Syncing of memory and database objects upon changes in objects in memory

I am currently implementing a web application in .net core(C#) using entity framework. While working on the project, I actually encountered quite a few challenges but I will start with the one which I think are most important. My questions are as follows:
Instead of frequent loading data from the database, I am having a set of static objects which is a mirror of the data in the database. However, it is tedious and error prone when I want to ensure any changes, i.e., adding/deleting/modifying of objects are being saved to the database at real time. Is there any good example or advice that I can refer to improve my approach to do this?
Another thing is that value of some objects' properties will be changed on the fly according to the value of some other objects' properties. Something like a spreadsheet where a cell's value will be changed automatically if the value in the cell that the formula is referring to changes. I do not have a solution to do this yet. Appreciate if anyone has any example that I can refer to. But this will add another layer of complexity to sync the changes of the objects in memory to database.
At the moment, I am unsure if there is any better approach. Appreciate if anyone can help. Thanks!
Basically, you're facing a problem that's called eventual consistency. Something changes and two or more systems need to be aware at the same time. The problem here is that both changes need to be applied in order to consider the operation successful. If either one fails, you need to know.
In your case, I would use the Azure Service Bus. You can create queues and put messages on a queue. An Azure Function would handle these queue messages. You would create two queues, one for database updates, and one for the in-memory update (I think changing this to a cache service may be something to think off). Now the advantage of these queues is that you can easily drop messages on these queues from anywhere. Because you mentioned the object is going to evolve, you may need to update these objects either in the database or in memory (cache).
Once you've done that, I'd create a topic, with two subscriptions. One forwarding messages to Queue 1, and the other to Queue 2. This will solve your primary problem. In case an object changes, just send it to the topic. Both changes (database and memory) will be executed automagically.
The only problem you have now, it that you mentioned you wanted to update the database in real-time. With this scenario, you're going to have to leave that.
Also, you need to make sure you have proper alerts in place for the queues so in case you did miss a message, or your functions didn't handle it well enough, you'll receive an alert to check & correct errors.
I'm totally agree with #nineedm's and answer, but there are also other solutions.
If you introduce cache, you will always face cache revalidation problem - you have to mark cache as invalid when data were changed. Sometimes it is easy, depending on nature of cached data and how often data are changed.
If you have just single application, MemoryCache can be enough with proper specified expiration options.
If there is a cluster - you have to look at Distributed Cache solutions, for example Redis. There is MS article about that Distributed caching in ASP.NET Core

What is the preferred way of server code notifying multiple clients of data changes within a single Delphi Application?

I have a large Delphi Application which has core 'server' code containing my data. Within the same app, 'client' the user is able to open and close multiple non-modal 'client' forms to inspect this data. Data changes fall into two types - major (e.g structural changes like data has been added or deleted) and minor such as a change to a data value. Existing open client forms must update to show changed data within a short-ish time. This is not a database, my 'server' using my own data structures so my solutions may have missed possibly standard techniques that are available within a formal database structure. That said, I have repeated my solutions so many times now that I thought I would ask if there are formal techniques and possibly Delphi components that would improve or simplify my code. I am about to move to multithreaded code which make the question even more relevant to me.
I use two methods:
Timestamp. The 'server' code maintains an Int64 value taken from QueryPerformanceCounter. Client forms examine this value on a 300ms ticking timer and update themselves if their copy of the timestamp differs from the server's. I guess this is my 'pull' solution.
Interface notification. The 'server' code maintains a class descended from TInterfaceList with AddClient and RemoveClient methods which register a simple common client notifcation interface. Each of the clients registers itself with this list when created and unregisters on destroy. Data changes at the server trigger an iteration through this list calling each client to advise it of change. I guess this is my 'push' solution.
I love interfaces and solution 2 seems nice since it avoides ticking timers and is easily debugged (although the unregister calls can be problematic with order of destruction). There are potential performance implications tooh because it is quite likely that there may be thousands of data changes per second and I have to be careful to use a BeginUpdate / EndUpdate mechanism to convert my many server data changes into one actual notification call. Ultimately I end up needing a timer of some kind to aggregate the calls into one gentle update of a displayed form.
Both solutions work nicely though and I'm torn between the two. For a mulithreaded solution I'm sure there are other pitfalls I know nothing about. Any comments would be appreciated. I'm using XE2.
You need to take into consideration what you want to happen when the number of clients grows, then decide between the two evils:
is it OK if my performance degrades while being sure all data is current, always and everywhere in the application (then you need the observer pattern)
is it OK if the data in some places lags behind in order to improve performance (then you could use polling and make the interval longer when the poll iterations cause too much slowdown)
I'm not a fan of polling, as it usually leads to very convoluted solutions (well, at least the things I tried, maybe I did it the wrong way back then).
I'd implement the Observer Pattern in Delphi using interfaces, you could use this or this as a start.
A used the Windows API to solve a problem similar to this one. But I believe my approach is simpler. In my applicaion I event didn't know the number of "clients" and which forms where actually clients.
What I did is:
Broadcast a Windows message to all forms opened by my application
(screen.forms[X]). The message includes in the WParam a pointer
to a record which contains information about an event. Also,
different actions broadcast distinc messages. WM_RECORDUPDATE
for DB updates for example.
Windows (clients) listen for message in the way of:
procedure RecordUpdateMessage(var msg: TMessage); message WM_RECORDUPDATE;
Procedure RecordUpdateMessage read the record pointed by msg.WParam and based on the data in the record desides if to react to the update, insert or delete of a record in the DB.

RAILS - Resource Pooling Options?

In my application I have a set of sessions for a third-party application I'm using.
I was planning on building a table to store the 10 or so sessions details I need for this and then writing a pool around this. Dishing out one of the unused connections as needed and then dropping it back in the pool when finished.
I was wondering if there are any good wrappers or gems out there that can handle some of this logic for me? It's one of those things that sounds like it should be simple, but I'm sure it'll end up being more complex than I imagine!
Any help or advice greatly appreciated.
Adding a bit more color
The third party application I'm using (OpenTok) provides web conferencing sessions. Once you open a session you're passed a session key (essentially just a string key). This key allows you to connect and disconnect from the session indefinitely.
If you want to have multiple sessions they recommend storing these sessions and reusing them when you want to open the session up.
I'd like to create maybe 10 or so of these sessions, store the 10 session keys in a table and then wrap a pool around these. They could be cached into memory on startup or read from the table each time.
I was just curious if there was any gems out there that handled this sort of pooling concept for a resource. In Java I might have used something like Apache Commons for the pooling for instance.
Just in case anyone else decides to look into this. There are actually quite a few options out there that do just this.
Some examples are:
https://github.com/guyboertje/client_pool
https://github.com/jugend/common-pool

creating new object again and again is bad practice . why ?

I heard numerous times that creating object for same database classes again and again is the bad practice.i really dont understand why is it so . Please somebody explain .
It's a bad idea in general , not just for database classes.
The more objects you have , the more memory being used to maintain your application.
For instance , take a look at: PHP Object Creation and Memory Usage
Hope I helped.
http://particletree.com/notebook/object-oriented-php-memory-concerns/
Have a look at that link to see how much memory is required to create an object (which has only 1 variable). Heavy class means bigger object. Having several memory-hungry scripts and a certain level of user base are enough to take up all memory in no time.
With regards to database classes, depending on whether the class opens up a connection on initialisation, as both the web server and database server have settings for maximum number of connections. The more objects you create, the more connections would be created which is not a good practice. One connection per database, if you can. If your database classes reuses the connection or use lazy initialisation to create the connection when required, you will still face the aforementioned memory problem.
To put it simply, reuse your objects (and your database connection).

WCF Windows Service not releasing resources/memory after every call

I have created WCF application which is running on Windows Service. It was installed using Windows Installer. I have followed procedure mentioned in following article for same.
http://msdn.microsoft.com/en-us/library/bb332338.aspx#msdnwcfhc_topic4
Most WCF properties are kept as default for net.tcp protocol, per call instance and so on.
Memory consumption of service keeps on increasing after every call and does not decrease. At the end it throws OutOfMemory consumption.
Application returns very heavy string based data. With memory-profiler I found memory is still allocated to string objects and increases during call.
As per my understanding string is managed objects should release data once out of scope.
Let me know if any other configuration/coding information is needed specifically.
There must be something keeping references to those strings in the code. Can you use your profiler to trace the references that are keeping the string objects alive?
After many unsuccessful attempts to handle LOH (http://msdn.microsoft.com/en-us/magazine/cc534993.aspx) which was very large string in my context, I have created custom class to handle it.
Instead of storing large string in single object am storing it as collection of small strings in custom object. .NET disposed it properly without creating above mentioned problem.
Other possible solution with worked for me is to use file object to store large file and access it as text reader. This works well and keeps footprint of application small. Unfortunately for me it did not work and accessing file location was not allowed for application.
It would be very difficult to answer this question without some code to look at. You can always call GC.Collect(GC.MaxGeneration) to force garbage collection and see if this doesn't reduce your memory consumption. Ideally this would only be temporary code to track down what is going on in the application. If forcing garbage collection does not reduce memory consumption then references to the strings must be being retained, via static member variables or whatever: having no conception of what the code is, any theory would be a shot in the dark

Resources