我正在开发一个REST服务(使用RESTeasy),它执行大量计算并产生大量结果(将被下载到文件中)。 为了保护系统,我们决定通过阻止并发调用来限制同一用户的执行。
我想在会话中添加一个变量,如下所示:
//check if service is running before execution
if (Boolean.parseBoolean((String) session.getAttribute("isRunning"))) {
throw new WebApplicationException(Response.status(
Response.Status.FORBIDDEN).entity("Service is currently running!").build());
}
//on execution
session.setAttribute("isRunning", "true");
//after execution
finally {
session.setAttribute("isRunning", "false");
}
但这会限制每次会话,不是每个用户。
答案 0 :(得分:1)
你走在正确的轨道上。
在会话中存储一个集合(我将其称为UserSet)。
当你收到请求时, 执行以下操作:
编辑:根据John Wu评论纠正范围。
答案 1 :(得分:0)
基于@dwb建议的方法,这是我的回答:
//globally defined set holding ids of users currently executing the service
private static Set<String> currentUsers = Collections.synchronizedSortedSet(new TreeSet<String>());
//check if service is running before execution
if (isCurrentlyRunningByUser(request.getRemoteUser())) {
throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN).entity("Service is currently running!").build());
}
//after execution
finally {
currentUsers.remove(user);
}
/**
* checks if user is currently running the service. if yes, returns true.
* if no, add user to current users set, and returns false
* @param remoteUser user asking to execute the service
* @return true if service is being run by the user
*/
private boolean isCurrentlyRunningByUser(String user) {
synchronized (currentUsers) {
Iterator it = currentUsers.iterator();
while (it.hasNext()) {
if (user.equals(it.next())) {
return true;
}
}
currentUsers.add(user);
}
return false;
}