Use Moqui Framework to build enterprise applications based on Java. It includes tools for databases (relational, graph, document), local and web services, web and other UI with screens and forms, security, file/resource access, scripts, templates, l10n, caching, logging, search, rules, workflow, multi-instance, and integration.
@Override String getLoginKey(float expireHours) {
String userId = getUserId()
if (!userId) throw new AuthenticationRequiredException("No active user, cannot get login key")
// generate login key
String loginKey = StringUtilities.getRandomString(40)
// save hashed in UserLoginKey, calc expire and set from/thru dates
String hashedKey = eci.ecfi.getSimpleHash(loginKey, "", eci.ecfi.getLoginKeyHashType(), false)
Timestamp fromDate = getNowTimestamp()
long thruTime = fromDate.getTime() + Math.round(expireHours * 60*60*1000)
eci.serviceFacade.sync().name("create", "moqui.security.UserLoginKey")
.parameters([loginKey:hashedKey, userId:userId, fromDate:fromDate, thruDate:new Timestamp(thruTime)])
.disableAuthz().requireNewTransaction(true).call()
// clean out expired keys
eci.entity.find("moqui.security.UserLoginKey").condition("userId", userId)
.condition("thruDate", EntityCondition.LESS_THAN, fromDate).disableAuthz().deleteAll()
return loginKey
}
The deleteAll() operation is not a batch deletion. Instead, delete one by one in the for loop. If there is a lot of user login information, it can greatly affect performance.
For example, in our current scenario, we use an anonymous user to access some interfaces that do not require login before the user logs in, such as the homepage product list. So every day, the login information of this anonymous user can reach several hundred thousand. Once it expires and needs to be deleted, tens of thousands of entries may need to be deleted at once, and then multiple users will come and delete it at the same time. This login interface will time out due to slow deletion.
There are two optimization suggestions:
Do not delete in a loop, but delete in batches based on time. For example:
DELETE from user Login Key where USER ID=? And THRU DATE<?
It can be deleted asynchronously, and even use jobs to fix a certain point in the evening when users are not using them.
Refer to the code for getLoginKey, as follows:
The deleteAll() operation is not a batch deletion. Instead, delete one by one in the for loop. If there is a lot of user login information, it can greatly affect performance. For example, in our current scenario, we use an anonymous user to access some interfaces that do not require login before the user logs in, such as the homepage product list. So every day, the login information of this anonymous user can reach several hundred thousand. Once it expires and needs to be deleted, tens of thousands of entries may need to be deleted at once, and then multiple users will come and delete it at the same time. This login interface will time out due to slow deletion.
There are two optimization suggestions: