Skip to content

Commit 472e1dc

Browse files
committed
refactor: 优化权限初始化逻辑
1 parent 3811266 commit 472e1dc

4 files changed

Lines changed: 45 additions & 20 deletions

File tree

jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/dimension/UserAuthenticationEventPublisher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public void handleEvent(ClearUserAuthorizationCacheEvent event) {
8080
private Mono<Void> publish0(Collection<String> userIdList) {
8181
return Flux
8282
.fromIterable(userIdList)
83-
.flatMapDelayError(
83+
.flatMap(
8484
userId -> eventBus
8585
.publish(Topics.Authentications.userAuthenticationChanged(userId),
8686
ReactiveAuthenticationHolder

jetlinks-manager/authentication-manager/src/main/java/org/jetlinks/community/auth/service/DefaultMenuService.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.jetlinks.community.auth.service;
1717

18+
import com.google.common.cache.CacheBuilder;
1819
import lombok.Generated;
1920
import lombok.extern.slf4j.Slf4j;
2021
import org.apache.commons.collections4.CollectionUtils;
@@ -50,6 +51,7 @@
5051
import reactor.core.publisher.Mono;
5152
import reactor.math.MathFlux;
5253

54+
import java.time.Duration;
5355
import java.util.*;
5456
import java.util.function.Function;
5557
import java.util.function.Predicate;
@@ -161,6 +163,13 @@ public Flux<MenuView> getGrantedMenus(QueryParamEntity queryParam, List<Dimensio
161163
.as(this::convertToView);
162164
}
163165

166+
final Map<List<String>, Flux<MenuView>> grantedCaching =
167+
CacheBuilder
168+
.newBuilder()
169+
.expireAfterAccess(Duration.ofSeconds(10))
170+
.<List<String>, Flux<MenuView>>build()
171+
.asMap();
172+
164173
public Flux<MenuView> getGrantedMenus(List<Dimension> dimensions,
165174
Mono<Map<String, MenuEntity>> menuEntityMap) {
166175
if (CollectionUtils.isEmpty(dimensions)) {
@@ -170,16 +179,25 @@ public Flux<MenuView> getGrantedMenus(List<Dimension> dimensions,
170179
.stream()
171180
.filter(this::isMenuDimension)
172181
.map(dimension -> MenuBindEntity.generateTargetKey(dimension.getType().getId(), dimension.getId()))
182+
.sorted()
173183
.collect(Collectors.toList());
174184

175-
return convertToView(CollectionUtils.isEmpty(keyList)
176-
? Flux.empty()
177-
: bindRepository
178-
.createQuery()
179-
.where()
180-
.in(MenuBindEntity::getTargetKey, keyList)
181-
.fetch(),
182-
menuEntityMap);
185+
return grantedCaching
186+
.computeIfAbsent(keyList,
187+
_keyList -> Flux
188+
.defer(() -> this
189+
.convertToView(CollectionUtils.isEmpty(_keyList)
190+
? Flux.empty()
191+
: bindRepository
192+
.createQuery()
193+
.where()
194+
.in(MenuBindEntity::getTargetKey, _keyList)
195+
.fetch(),
196+
menuEntityMap))
197+
// 缓存1秒钟,避免编辑角色或者组织时,导致大量用户权限失效并进行初始化时执行大量重复的查询.
198+
.cache(Duration.ofSeconds(1)));
199+
200+
183201
}
184202

185203
private boolean isMenuDimension(Dimension dimension) {
@@ -204,7 +222,6 @@ public Flux<MenuView> getGrantedMenus(String dimensionType, Collection<String> d
204222
}
205223

206224

207-
208225
private Flux<MenuView> convertToView(Flux<MenuBindEntity> entityFlux, Mono<Map<String, MenuEntity>> menuEntityMap) {
209226
return Mono
210227
.zip(

jetlinks-manager/notify-manager/src/main/java/org/jetlinks/community/notify/manager/service/NotifySubscriberService.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import lombok.AllArgsConstructor;
1919
import lombok.extern.slf4j.Slf4j;
20+
import org.apache.commons.collections4.CollectionUtils;
2021
import org.apache.commons.collections4.MapUtils;
2122
import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
2223
import org.hswebframework.web.authorization.Authentication;
@@ -26,6 +27,8 @@
2627
import org.hswebframework.web.exception.BusinessException;
2728
import org.hswebframework.web.i18n.LocaleUtils;
2829
import org.jetlinks.community.gateway.annotation.Subscribe;
30+
import org.jetlinks.community.lock.ReactiveLock;
31+
import org.jetlinks.community.lock.ReactiveLockHolder;
2932
import org.jetlinks.community.notify.manager.configuration.NotifySubscriberProperties;
3033
import org.jetlinks.community.notify.manager.entity.Notification;
3134
import org.jetlinks.community.notify.manager.entity.NotifySubscriberChannelEntity;
@@ -56,6 +59,7 @@
5659

5760
import java.util.*;
5861
import java.util.concurrent.ConcurrentHashMap;
62+
import java.util.concurrent.ThreadLocalRandom;
5963
import java.util.stream.Collectors;
6064

6165
@Service
@@ -463,13 +467,9 @@ Mono<Void> resubscribe(NotifySubscriberProviderEntity entity) {
463467
}
464468

465469
public void handleSubscriberEntity(NotifySubscriberEntity entity) {
466-
NotifySubscriberProviderCache cache = providerChannels.get(entity.getProviderId());
467-
NotifySubscriberProviderEntity provider = null;
468-
if (cache != null) {
469-
provider = cache.getProvider();
470-
}
471-
//取消订阅
472-
if ((provider != null && provider.getState() == NotifyChannelState.disabled) || entity.getState() == SubscribeState.disabled) {
470+
// 取消订阅,没有订阅通道也取消,减少内存占用。
471+
if (entity.getState() == SubscribeState.disabled
472+
|| CollectionUtils.isEmpty(entity.getNotifyChannels())) {
473473
Disposable disp = subs.remove(entity.getId());
474474
if (disp != null) {
475475
log.debug("unsubscribe:{}({}),{},subscriber:{}",
@@ -483,8 +483,7 @@ public void handleSubscriberEntity(NotifySubscriberEntity entity) {
483483
return;
484484
}
485485

486-
subs.computeIfAbsent(entity.getId(), ignore -> new Node())
487-
.init(entity);
486+
subs.computeIfAbsent(entity.getId(), ignore -> new Node()).init(entity);
488487
}
489488

490489
@Override
@@ -521,8 +520,15 @@ public void init(NotifySubscriberEntity entity) {
521520
disposable.dispose();
522521
}
523522

523+
// fixme 使用锁来限制并发
524+
ReactiveLock lock = ReactiveLockHolder
525+
.getLock("subscriber_loader:" +
526+
ThreadLocalRandom.current().nextInt(
527+
0,
528+
Runtime.getRuntime().availableProcessors()));
524529
disposable = Mono
525-
.zip(ReactiveAuthenticationHolder.get(entity.getSubscriber()), getProvider(entity))
530+
.zip(ReactiveAuthenticationHolder.get(entity.getSubscriber()).as(lock::lock),
531+
getProvider(entity))
526532
.flatMap(tp2 -> {
527533
initNotifyChannels(tp2.getT1());
528534
return tp2.getT2().createSubscriber(entity.getId(), tp2.getT1(), entity.getTopicConfig());

jetlinks-standalone/src/main/resources/application.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ hsweb:
120120
# allopatric-login-modes:
121121
# app: offlineOther
122122
permission:
123+
initialize:
124+
enabled-dimensions: api-client
123125
filter:
124126
enabled: true # 设置为true开启权限过滤,赋权时,不能赋予比自己多的权限.
125127
exclude-username: admin # admin用户不受上述限制

0 commit comments

Comments
 (0)