Heavy database load when using CodeIgniter Session class? - database

After reading about how CodeIgniter handles sessions, it has me concerned about the performance impact when sessions are configured to be stored and retrieved from the database.
This is from the CI documentation: "When session data is available in a database, every time a valid session is found in the user's cookie, a database query is performed to match it."
So every AJAX call, every HTML fragment I request is going to have this overhead? That is potentially a huge issue for systems that are trying to scale!
I would have guessed that CI would have implemented it better: include the MD5 hash to cover both the sessionID+timestamp when encoding them in the session record. Then only check the database for the session record every X minutes whenever the sessionID gets regenerated. Am I missing something?

You can make your AJAX requests use a different controller, for example Ajax_Controller instead of MY_Controller. MY_Controller would load the Session class but the Ajax_Controller doesn't. That way when you call to your AJAX, it doesn't touch session data and therefore doesn't make any erroneous calls to the database that aren't necessary.
If you are autoloading the Session class, maybe you can try unloading it for the AJAX requests? I've never tried it but it's talked about here http://codeigniter.com/forums/viewthread/65191/#320552 and then do something like this
if($this->input->is_ajax_request()){
// unload session class code goes here
}

Related

Pattern/approach for frontend-backend data integration and fetching

I have been applying a pattern in some small apps I worked on, which next tools:
Frontend: ReactJS, Redux, Firebase (only authentication stuff)
Backend: Node with Express and the library for the database I was using (mysql or mongo)
The flow used to be like this:
Page loading and validating if user is signed in. If yes, fetching app data with backend. If not, just checking if user is not on a protected route and then let him navigate (create account, reset password, etc)
When fetch occurs and user signed in, backend send all data from that user (categories, stores, products, profile and any other info to let application run fluid) so when navigating there is not continuously loading to fetch each chunk of data. This also happens like this because is not a big amount of data (at the beginning), lets say maybe 1 or 2 stores with 15-20 products each one.
When updating data like changing product name, price or any kind of data mutation, the frontend send a request to the backend and then the update is done and a response of success true/false is sent as an answer for the request.
Let's say the previous step is a store creation. So, the frontend receives the success response and then dispatch an APPEND_STORE event to redux store to catch the new store with its data (only the ID + other data which is created on the backend is received as response on http request, data which was generated at the frontend is taken from the app itself) and append it to the stores array and then set the store array object again.
The reason why the previous step occurs like that is to avoid the backend first make the update and then make a new query to get again the new register (ej: create new store request -> backend creates the store and retrieve the new ID -> backend find/query the new register with its ID -> answer the data)
So, basically the question is about the pattern. So far this pattern had not give big troubles by now but I'm pretty sure there are some details I haven't seen from this point and also I think there are recommended ways to handle this that I couldn't find on internet yet.
I would like to know the best approach for this (or at least a better approach from the above) in order to implement it to bigger applications to handle more users and data which will increase as time goes.
Main questions:
When loading, should the backend process all data and send it to the frontend or should send minimal data to let the application begin and then send as navigation requires? I was also thinking when data grows up send a chunk of data with limit of 10/20 registers to keep the same approach but want to know the standard/correct way to handle it.
When a data validation fails on backend, should the backend answer with an OK status code with a key called success: "true/false" and additional data to handle this on the frontend, or should the backend answer with an error status code?
As I said, backend only answer with the data created by backend itself (ID, creation date, etc). Should the backend answer only with this or should backend make a new query to get full register and send it as response? Initially took this approach in order to optimize resources (minimum quantity of request and data sent by response). I'm also thinking maybe this is a dumb approach because today's world have a lot of resources so that difference should not change performance of anything. Also, with this answer my behavior on redux will change. Do you have any comments also from this redux approach?
Is it ok to make a query to database to first update and then another query to fetch all registered again? I know databases are created to handle multiple queries but I don't know if there are some cons to take on mind when doing like this.
Really thanks!

Does JMeter scripts actually creates records in database

Let's say I run a recorded script for 'New User Registration' function of a web site to evaluate the response time for entire scenario. When I run the recorded script from JMeter, for each registration script, is there a new user record getting created in the application database ?
Yes, if you record registration and correlate it (meaning you create a valid unique name for every request) you will create a real user in your environment.
JMeter is simulating a real scenario which effect your environment.
That is part of the reason JMeter will be executed in different environment than production (as stage)
Well-behaved JMeter script must represent a real user using a real browser as close as it is possible.
Browsers execute HTTP requests and render the response
JMeter executes the same HTTP requests but doesn't render the response, instead it records performance metrics like response time, connect time, latency, throughput, etc.
HTTP is a stateful protocol therefore given you execute the same request you will get the same response. So if there are no mistakes in your script it either should create a new user or fail due to non-unique username error.
Yes, if your script accurately represents the full set of data flows associated with the business process, "New User Registration," then the end state of that process should be identical to that of the user behavior so modeled.
A record will be created in the database. If not, then your user is not accurate in its behavior

webapp2 Sessions: How do sessions work conceptually?

I wish to implement sessions in webapp2. From research, I have found this code sample using webapp2_extra.sessions, and a few articles which mentions deprecated or unmaintained session libraries.
I currently lack the knowledge of how sessions work conceptually. This is what I understand so far:
We can include a dispatch() method to a request handler which allows us to create/update a session object; it is during the login phase of the app, the session is created. (Question: how is session stored? In the app's memory or in datastore?)
When a user makes a request to the app, the dispatch() method checks to see if an existing session exists for the user. (Question: How exactly does this validation work? Is there a token inside the request.body or cookie that sessions look for?)
When a user logs out, the session is deleted.
Is my understanding correct? Or perhaps I am missing something important? There seems to be little guidance on this subject on the internet. Thank you for the assistance.
Technically the dispatch() method is not added, it's just overwriting the one that webapp2.RequestHandler already provides, extending it to add session support. If you take a closer look at that method you see that it still calls the original one to do the actual dispatching:
# Dispatch the request.
webapp2.RequestHandler.dispatch(self)
Which could be re-written, if you want, as:
super(BaseHandler, self).dispatch()
All that the extended dispatch() does is picking up the session info from the store making it available to the handler code before dispatching the request (which BTW includes the request processing) and saving it back afterwards, when the request processing completes (when changes to the session info may have been done). For every request! Simply a way to persist info across requests.
The session support is simply that - support - your app is still the one responsible for controlling what info is stored in the webapp2's session dictionary, when is that info added/modified/deleted and how is that info used.
In other words webapp2 itself has no clue what's login/logout/user session, etc (So no, nothing that you mention in #1, #2 and #3 happens in webapp2 itself). It is your app's responsibility to:
set/delete inside the session dictionary the info that represents your "user session" (whatever that means for your app) - typically in the user login/logout request handlers, respectively
use that info as it sees fit while handling incoming requests between the login and the logout one - when the info from the session dictionary represents the "current user session".
For storing the session info webapp2 supports cookies (default), memcache and datastore (ndb). From Sessions:
It has three built-in backends: secure cookies, memcache and
datastore. New backends can be added extending
CustomBackendSessionFactory.
The session store can provide multiple sessions using different keys,
even using different backends in the same request, through the method
SessionStore.get_session(). By default it returns a session using
the default key from configuration.

Building a Cart with Laravel and Angular

I have in my application a cart, it currently works for me, though the issue my colleague is having is that it is too "slow". I have been thinking of a better way to implement this to make it faster and efficient.
Currently this is how my page loads:
Product/Ticket page loads.
AJAX function gets products/tickets from server and displays on the page.
Each product has a buy button like this:
<button ng-click="buyTicket(id)" class="btn">Buy Ticket</button>
This is how the buyticket works:
I pass the id of the product/ticket to my function.
AJAX function posts id to server.
Server runs a database query to retrieve product/ticket information based on id.
Product/ticket information is saved into "cart" table.
AJAX function returns with data "true" as the response.
I broadcast this:
$rootScope.$broadcast('TICKET_ADDED', true);
Cart directive listens to broadcast and makes an AJAX call to server to get cart data:
$scope.$on('TICKET_ADDED', function(response) {
$scope.loadCart();
})
Data returned is assigned to an array and displayed in the cart.
Each user cart is identified by a randomly generated string of length 25.
That is how my cart works for now, i would like a faster, better way to do this please.
Edit: (used a debug bar to get these statistics)
When page loads:
No. of queries run: 1
Memory Usage: 12.25 MB
Request Duration: 1.04s
No. of AJAX requests: 3
When buy ticket function is clicked:
No. of queries run: 5
Memory Usage: 12.75 MB
Request Duration: 934.41 ms
No. of AJAX requests: 2
The approach you are using is fine, just the thing is you might not have used caching. Use caching & you will get a good Speed. Also check your server response time, speed etc. on Google Speed Insights. It will tell you how you can make it more fact. Hope it helps.
vJ
You can improve performance by introducing caching, both server side and client side.
Server side caching: instead of doing a DB query every time, keep objects in memory for some period of time. You can define a 'time to live' for an object and if the object has 'expired', you requery the db.
There are probably plenty of libraries out there that support this kind of functionality, but I would simply build it myself, because it's not that complicated. The trickiest part is making sure that nothing breaks down when multiple threads are trying to modify your collection of cached objects.
Client side caching is a breeze when you use angular. This is from the documentation of $http:
To enable caching, set the request configuration cache property to
true (to use default cache) or to a custom cache object (built with
$cacheFactory). When the cache is enabled, $http stores the response
from the server in the specified cache. The next time the same request
is made, the response is served from the cache without sending a
request to the server.

Google App Engine: keep state of an object between HTTP-requests (Java)

User makes HTTP-request to the server. This request is processed with an object of some class, let's call it "Processor". Then the same user in two minutes makes another HTTP request. And I want it to be processed with the same instance of Processor as the first one. So basically I want to keep the state of some object among several requests.
I know that I can save it each time to the datastore and then load back, but this approach seems to be very slow. Is there a way to store objects in some RAM place?
How about using memcache?
You can't ensure that consecutive requests to your app will go to the same instance, but memcache can help reduce or eliminate the overhead of accessing the datastore for each request.
It sounds like you are describing is a session.
I am not sure which language runtime and web framework you are using, but it is sure to include support for a sessions. (If you are using Java you will need to enable it.)
The standard session mechanism puts a small ID in a cookie that is stored in the user's browser. On every request, each of which could be go to a different application server, this ID is used as a key to read and write persistent information from the data store.
If the datastore accesses are too slow for you I would suggest not using memcache for this session storage, because memcache is by design unreliable, so the user's session information could disappear at any time, which would be a bad experience for them.
If the amount of data you want to store is less than about a few kilobytes, then I recommend doing what Play Framework does, which is to encrypt your session data and store it directly in a cookie stored in the user's browser. This is fast and truly stateless.
If you have more data than can be stored in a cookie, and you don't want to use the data store, you could could use JavaScript local storage on the browser, and use AJAX calls to communicate with the server. (If you want to support older browsers you may need to use the jStorage wrapper library.)
If memcache isn't enough, you could use backends to maintain state. Use a resident backend (or a set of them) and route incoming requests from the frontend to the backend machine that has the state.
Docs: Python Java

Resources