You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ha...@apache.org on 2020/12/07 13:09:02 UTC

[skywalking] 02/02: Fix MAL concurrent issues

This is an automated email from the ASF dual-hosted git repository.

hanahmily pushed a commit to branch mal-patch
in repository https://gitbox.apache.org/repos/asf/skywalking.git

commit ed7302098b5a1359a5a7efe481ee441b50c4220b
Author: Gao Hongtao <ha...@gmail.com>
AuthorDate: Mon Dec 7 21:07:58 2020 +0800

    Fix MAL concurrent issues
    
    Signed-off-by: Gao Hongtao <ha...@gmail.com>
---
 .../oap/meter/analyzer/dsl/Expression.java         | 50 ++++++++++++++--------
 .../meter/analyzer/dsl/ExpressionParsingTest.java  |  1 +
 2 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/Expression.java b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/Expression.java
index 0cedea9..7cf84f6 100644
--- a/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/Expression.java
+++ b/oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/dsl/Expression.java
@@ -23,7 +23,6 @@ import groovy.lang.ExpandoMetaClass;
 import groovy.lang.GroovyObjectSupport;
 import groovy.util.DelegatingScript;
 import java.time.Instant;
-import lombok.RequiredArgsConstructor;
 import lombok.ToString;
 import lombok.extern.slf4j.Slf4j;
 
@@ -31,7 +30,6 @@ import lombok.extern.slf4j.Slf4j;
  * Expression is a reusable monadic container type which represents a DSL expression.
  */
 @Slf4j
-@RequiredArgsConstructor
 @ToString(of = {"literal"})
 public class Expression {
 
@@ -39,6 +37,14 @@ public class Expression {
 
     private final DelegatingScript expression;
 
+    private final ThreadLocal<ImmutableMap<String, SampleFamily>> propertyRepository = new ThreadLocal<>();
+
+    public Expression(final String literal, final DelegatingScript expression) {
+        this.literal = literal;
+        this.expression = expression;
+        this.empower();
+    }
+
     /**
      * Parse the expression statically.
      *
@@ -65,10 +71,35 @@ public class Expression {
      * @return The result of execution.
      */
     public Result run(final ImmutableMap<String, SampleFamily> sampleFamilies) {
+        propertyRepository.set(sampleFamilies);
+        try {
+            SampleFamily sf = (SampleFamily) expression.run();
+            if (sf == SampleFamily.EMPTY) {
+                if (!ExpressionParsingContext.get().isPresent()) {
+                    if (log.isDebugEnabled()) {
+                        log.debug("result of {} is empty by \"{}\"", sampleFamilies, literal);
+                    }
+                }
+                return Result.fail("Parsed result is an EMPTY sample family");
+            }
+            return Result.success(sf);
+        } catch (Throwable t) {
+            log.error("failed to run \"{}\"", literal, t);
+            return Result.fail(t);
+        } finally {
+            propertyRepository.remove();
+        }
+    }
+
+    private void empower() {
         expression.setDelegate(new GroovyObjectSupport() {
 
             public SampleFamily propertyMissing(String metricName) {
                 ExpressionParsingContext.get().ifPresent(ctx -> ctx.samples.add(metricName));
+                ImmutableMap<String, SampleFamily> sampleFamilies = propertyRepository.get();
+                if (sampleFamilies == null) {
+                    return SampleFamily.EMPTY;
+                }
                 if (sampleFamilies.containsKey(metricName)) {
                     return sampleFamilies.get(metricName);
                 }
@@ -94,21 +125,6 @@ public class Expression {
 
         });
         extendNumber(Number.class);
-        try {
-            SampleFamily sf = (SampleFamily) expression.run();
-            if (sf == SampleFamily.EMPTY) {
-                if (!ExpressionParsingContext.get().isPresent()) {
-                    if (log.isDebugEnabled()) {
-                        log.debug("result of {} is empty by \"{}\"", sampleFamilies, literal);
-                    }
-                }
-                return Result.fail("Parsed result is an EMPTY sample family");
-            }
-            return Result.success(sf);
-        } catch (Throwable t) {
-            log.error("failed to run \"{}\"", literal, t);
-            return Result.fail(t);
-        }
     }
 
     private void extendNumber(Class clazz) {
diff --git a/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/ExpressionParsingTest.java b/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/ExpressionParsingTest.java
index 540362e..cca1801 100644
--- a/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/ExpressionParsingTest.java
+++ b/oap-server/analyzer/meter-analyzer/src/test/java/org/apache/skywalking/oap/meter/analyzer/dsl/ExpressionParsingTest.java
@@ -65,6 +65,7 @@ public class ExpressionParsingTest {
                 "all",
                 "latest (foo - 1).tagEqual('bar', '1').sum(['tt']).irate().histogram().histogram_percentile([50,99]).service(['rr'])",
                 ExpressionParsingContext.builder()
+                                        .samples(Collections.singletonList("foo"))
                                         .scopeType(ScopeType.SERVICE)
                                         .scopeLabels(Collections.singletonList("rr"))
                                         .aggregationLabels(Collections.singletonList("tt"))