There is nothing wrong with that. On every hit there may be dozens and even way more DB hits (depending on the applications complexity of your app) for a full page request. You may use a cache if you want to not have always a query. Using the application scope isnt the right place fore that. If you have a static list you may set the IDs into a component where you save the values. But a DB table is where you handle all of this.
Yeah, fair enough actually.
This just seems like a āflinging shit at the wallā sort of solution, if Iām to be frank; rather than a well-designed solution.
Andreas is on to something here:
OK, so have a UserService
(and this is persisted in the application scope) which one talks to when servicing actions like user record updates.
When thereās a ādisable userā event (ie: someoneās updated a user info form and deselected the āactiveā value), then send a message to a RecentlyDisabledUsersManager
(this could just be a method in the UserService
which maintains an array of user IDs), which appends to that array.
When there is user activity - an incoming request from a user - call the UserService
and tell it to go check with the RecentlyDisabledUsersManager
. Itāll respond telling the UserService
āyeah theyāre a no-goā, and the UserService
a) invalidates that session and b) passes that back to the controller method, and the controller method responds with a 403. Or maybe itās the controllerās job to invalidate the session, given itās perhaps more a request/response-layer sort of thing?
Thinking about it some more, I donāt think you need to do any further persistence of that array, provided the application timeout is longer than the session timeout. Also provided that when the application restarts, sessions also restart. This is dependent on your session storage, and you will need to test this.
Also I donāt think you need some sort of GC on that array - ie: remove entries that have been ādealt withā. As you say, the same user might have a session on multiple client agents, so itās not like itās a one-and-done when locking them out. Also itās not much data - some IDs - and I donāt think one will be deactivating so many users one needs to worry about it getting too big. Something to deal with if it ever becomes a problem, I guess.
You are right, this is not something that Iāll be doing on a regular basis, quite the opposite, but if an account is disabled itās likely I want them out right away.
Unfortunately my skill set is such that I donāt understand what the userservice is doing and how that works. On the surface it sounds like a similar way to what I was thinking with a list that it just checks each time for the user ID, but I suspect I am just not getting it.
You oughtnāt be going ādonāt currently understand, so not doing thatā, you ought to be going āright⦠well⦠I need to lift my gameā.
Look around the room you are in. Do you just have stacks of books, piles of plates, random sheets of paper around the place? An area marked out with string with a sign ācoffee cups in hereā? Or have you got bookshelves, cupboards, separate rooms, etc? A place for everything, and everything in its place (to a degree, at least). I mean of course you have your meatspace considerations organised. Why is it - apparently - OK to not do the same in oneās professional work? This is not aimed solely at you, @aspirenet ⦠itās something I marvel about with really a lot of CFML devs I encounter.
A āUserServiceā is just a file called UserService.cfc where one organises user-oriented functionality into.
A RecentlyDisabledUsersManager like I said could just be a method in that CFC, backed with an array.
Minimum level of organisation of oneās code is table stakes for showing up to our jobs each day.
Second thing⦠lists are just strings with an acknowledged character delimiters. They are not a collection type, and should not be used for persisting multiple values. Thatās what arrays, structs, objects, etc are for. List functionality should only be used when receiving a string from an external source that needs to be processed as a collection (converting a para of text to an array of words, for example); or - for some reason - coverting a collection type back into a string (emiting a word collection as a comma-delimited list in some text output, for example.
Donāt use them internally for storing collections of values.
Hey @AdamCameron a rather feisty reply, I did not say I was not going to do it, I said I didnāt understand. I actually would like to understand and improve on my skills
Obvs communication is a two way street. I read your response - incorrectly it seems as - ādonāt understand. Sticking with my approachā.
Did my clarification⦠erm⦠clarify? Happy to work with you to get it sorted if you give it a go.
Another approach you could take when encountering concepts you donāt understand is⦠look them up. Iām not inventing my own jargon here: the concept of services and application design in general are well trod ground. In that they seem to be concepts that perplex you does - Iām afraid - suggest to me a lack of technical investment on your part.
[from your ābioā on these forums]: Never became a guru of CF despite developing in it since version 3 in 1998
This is - IMO - an indictment, not a badge of honour.
Obvs what you do with your time is entirely your call. And you are not even an exception in the CFML community. But equally itās my call to be disheartened by this state of affairs.
I donāt make any secret that I am no guru, I prefer it to be known, so that others understand there may be advanced concepts that I may not fully understand or need help with.
I use CFML to create my own projects, which may not be technically the very best, but they are adequate enough to get the job done.
Unfortunately as I wear many, many hats, I donāt have enough time and in reality I get by and the code serves me well with no issues.
I am interested in your approach, Iām always interested in improving. In-fact I did try making some CFCās after I read your post, but I could not get them working and yes, I did Google search and I even spoke to my friend ChatGPT which is actually pretty good at helping get to a solution.
Fair enough, all good. Your decision etc.
Happy to help with the CFCs. I mean I reckon given I complain about you know knowing them⦠I should do my bit to help you with them. Quid pro quo 'nāall.
How best to do that? I think it would be A-OK to post a separate thread here saying ātrying to get this bloody CFC working but stuck on⦠etcā?
Whoops I missed a few replies. I am certainly interested in improving on my skillset and that includes CFCās. However I reflected on this particular task and how much time itās taking and how much it will actually be used vs time needed to complete my project! I decided although not the most elegant as it requires a drop of manual maintenance to add a little code to the application.cfm where I maintain a list of user UIDās that I need to block (which wonāt happen very often)
So if I want to block user 10000000 itāll be
<CFIF ListFind(ā10000000ā, #session.aff_uid#)>
<CFSCRIPT>sessionInvalidate();</CFSCRIPT>
<CFLOCATION URL=ā/inactiveaccount.cfmā addtoken=ānoā>
</CFIF>
Replaced < with & lt; to display all code. I must be missing an option in here somewhere to stop this
You can post code without the need for escaping angle brackets by enclosing it in backticks (``).
Example: <cfscript>
Or post an entire code block by either clicking the āPreformatted textā icon or via the Ctrl+E keyboard shortcut:
<cfscript>
// example
</cfscript>
You can also delete a post by clicking the three dots then the trash can.