Skip to content

Commit

Permalink
Apply volatile modifier for fields in FlowRuleManager while keep conc…
Browse files Browse the repository at this point in the history
…urrency semantics intact (#2107)

- Revert #1783
  • Loading branch information
JerryChin authored and sczyh30 committed Apr 27, 2021
1 parent e936d9d commit 36b162c
Showing 1 changed file with 17 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@
package com.alibaba.csp.sentinel.slots.block.flow;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory;
import com.alibaba.csp.sentinel.config.SentinelConfig;
Expand All @@ -50,7 +48,7 @@
*/
public class FlowRuleManager {

private static final AtomicReference<Map<String, List<FlowRule>>> flowRules = new AtomicReference<Map<String, List<FlowRule>>>();
private static volatile Map<String, List<FlowRule>> flowRules = new HashMap<>();

private static final FlowPropertyListener LISTENER = new FlowPropertyListener();
private static SentinelProperty<List<FlowRule>> currentProperty = new DynamicSentinelProperty<List<FlowRule>>();
Expand All @@ -60,11 +58,10 @@ public class FlowRuleManager {
new NamedThreadFactory("sentinel-metrics-record-task", true));

static {
flowRules.set(Collections.<String, List<FlowRule>>emptyMap());
currentProperty.addListener(LISTENER);
startMetricTimerListener();
}

/**
* <p> Start the MetricTimerListener
* <ol>
Expand All @@ -79,12 +76,12 @@ private static void startMetricTimerListener() {
if (flushInterval <= 0) {
RecordLog.info("[FlowRuleManager] The MetricTimerListener isn't started. If you want to start it, "
+ "please change the value(current: {}) of config({}) more than 0 to start it.", flushInterval,
SentinelConfig.METRIC_FLUSH_INTERVAL);
SentinelConfig.METRIC_FLUSH_INTERVAL);
return;
}
SCHEDULER.scheduleAtFixedRate(new MetricTimerListener(), 0, flushInterval, TimeUnit.SECONDS);
}

/**
* Listen to the {@link SentinelProperty} for {@link FlowRule}s. The property is the source of {@link FlowRule}s.
* Flow rules can also be set by {@link #loadRules(List)} directly.
Expand All @@ -108,7 +105,7 @@ public static void register2Property(SentinelProperty<List<FlowRule>> property)
*/
public static List<FlowRule> getRules() {
List<FlowRule> rules = new ArrayList<FlowRule>();
for (Map.Entry<String, List<FlowRule>> entry : flowRules.get().entrySet()) {
for (Map.Entry<String, List<FlowRule>> entry : flowRules.entrySet()) {
rules.addAll(entry.getValue());
}
return rules;
Expand All @@ -124,19 +121,19 @@ public static void loadRules(List<FlowRule> rules) {
}

static Map<String, List<FlowRule>> getFlowRuleMap() {
return flowRules.get();
return flowRules;
}

public static boolean hasConfig(String resource) {
return flowRules.get().containsKey(resource);
return flowRules.containsKey(resource);
}

public static boolean isOtherOrigin(String origin, String resourceName) {
if (StringUtil.isEmpty(origin)) {
return false;
}

List<FlowRule> rules = flowRules.get().get(resourceName);
List<FlowRule> rules = flowRules.get(resourceName);

if (rules != null) {
for (FlowRule rule : rules) {
Expand All @@ -152,18 +149,20 @@ public static boolean isOtherOrigin(String origin, String resourceName) {
private static final class FlowPropertyListener implements PropertyListener<List<FlowRule>> {

@Override
public void configUpdate(List<FlowRule> value) {
public synchronized void configUpdate(List<FlowRule> value) {
Map<String, List<FlowRule>> rules = FlowRuleUtil.buildFlowRuleMap(value);
//the rules was always not null, it's no need to check nullable
//remove checking to avoid IDE warning
flowRules.set(rules);
if (rules != null) {
flowRules = rules;
}
RecordLog.info("[FlowRuleManager] Flow rules received: {}", rules);
}

@Override
public void configLoad(List<FlowRule> conf) {
public synchronized void configLoad(List<FlowRule> conf) {
Map<String, List<FlowRule>> rules = FlowRuleUtil.buildFlowRuleMap(conf);
flowRules.set(rules);
if (rules != null) {
flowRules = rules;
}
RecordLog.info("[FlowRuleManager] Flow rules loaded: {}", rules);
}
}
Expand Down

0 comments on commit 36b162c

Please sign in to comment.