[
https://issues.apache.org/jira/browse/GROOVY-9381?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18033305#comment-18033305
]
ASF GitHub Bot commented on GROOVY-9381:
----------------------------------------
Copilot commented on code in PR #2324:
URL: https://github.com/apache/groovy/pull/2324#discussion_r2466616981
##########
src/main/java/groovy/util/concurrent/async/AsyncHelper.java:
##########
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.util.concurrent.async;
+
+import org.apache.groovy.util.SystemUtil;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.function.Supplier;
+
+/**
+ * Helper class for async/await operations
+ *
+ * @since 6.0.0
+ */
+public class AsyncHelper {
+ private static final int PARALLELISM =
SystemUtil.getIntegerSafe("groovy.async.parallelism",
Runtime.getRuntime().availableProcessors() + 1);
+ private static final Executor DEFAULT_EXECUTOR;
+ private static int seq;
Review Comment:
The static field `seq` is accessed without synchronization in the thread
factory. This can lead to race conditions when multiple threads are created
concurrently, resulting in duplicate or inconsistent thread names. Use
`AtomicInteger` instead: `private static final AtomicInteger seq = new
AtomicInteger(0);` and update line 54 to `t.setName(\"async-thread-\" +
seq.getAndIncrement());`
##########
src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java:
##########
@@ -151,16 +155,222 @@
import java.util.stream.Collectors;
import static groovy.lang.Tuple.tuple;
-import static org.apache.groovy.parser.antlr4.GroovyParser.*;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ADD;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ARROW;
+import static org.apache.groovy.parser.antlr4.GroovyParser.AS;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ASYNC;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.AdditiveExprAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.AndExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.AnnotatedQualifiedClassNameContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.AnnotationContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.AnnotationNameContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.AnnotationsOptContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.AnonymousInnerClassDeclarationContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ArgumentsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ArrayInitializerContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.AssertStatementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.AssignmentExprAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.BlockContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.BlockStatementsOptContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.BooleanLiteralAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.BreakStatementContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.BuiltInTypeContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.CASE;
+import static org.apache.groovy.parser.antlr4.GroovyParser.CastExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.CastParExpressionContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.CatchClauseContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.CatchTypeContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ClassBodyContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ClassBodyDeclarationContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ClassDeclarationContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ClassNameContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifierContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifiersContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ClassOrInterfaceModifiersOptContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ClosureContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ClosureOrLambdaExpressionContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.CommandArgumentContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.CommandExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.CommandExpressionContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.CompactConstructorDeclarationContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.CompilationUnitContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ConditionalExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ConditionalStatementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ContinueStatementContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.CreatedNameContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.CreatorContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.DEC;
+import static org.apache.groovy.parser.antlr4.GroovyParser.DEF;
+import static org.apache.groovy.parser.antlr4.GroovyParser.DEFAULT;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.DoWhileStmtAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.DynamicMemberNameContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ElementValueArrayInitializerContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ElementValueContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ElementValuePairContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ElementValuePairsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ElementValuesContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.EnhancedArgumentListElementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.EnhancedArgumentListInParContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.EnhancedExpressionContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.EnhancedForControlContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.EnhancedStatementExpressionContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.EnumConstantContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.EnumConstantsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.EqualityExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ExclusiveOrExprAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ExpressionContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ExpressionInParContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ExpressionListContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ExpressionListElementContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.FINAL;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.FieldDeclarationContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.FinallyBlockContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.FloatingPointLiteralAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ForControlContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ForInitContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ForStmtAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ForUpdateContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.FormalParameterContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.FormalParameterListContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.FormalParametersContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.GE;
+import static org.apache.groovy.parser.antlr4.GroovyParser.GT;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.GroovyParserRuleContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.GstringContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.GstringPathContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.GstringValueContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.IN;
+import static org.apache.groovy.parser.antlr4.GroovyParser.INC;
+import static org.apache.groovy.parser.antlr4.GroovyParser.INSTANCEOF;
+import static org.apache.groovy.parser.antlr4.GroovyParser.IdentifierContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.IdentifierPrmrAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.IfElseStatementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ImplicationExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ImportDeclarationContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.InclusiveOrExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.IndexPropertyArgsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.IndexVariableContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.IntegerLiteralAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.KeywordsContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.LE;
+import static org.apache.groovy.parser.antlr4.GroovyParser.LT;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.LabeledStmtAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.LambdaBodyContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ListContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.LocalVariableDeclarationContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.LogicalAndExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.LogicalOrExprAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.LoopStmtAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.MapContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.MapEntryContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.MapEntryLabelContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.MapEntryListContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.MatchingTypeContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.MemberDeclarationContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.MethodBodyContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.MethodDeclarationContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.MethodNameContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ModifierContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ModifiersContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ModifiersOptContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.MultipleAssignmentExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.MultiplicativeExprAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.NON_SEALED;
+import static org.apache.groovy.parser.antlr4.GroovyParser.NOT_IN;
+import static org.apache.groovy.parser.antlr4.GroovyParser.NOT_INSTANCEOF;
+import static org.apache.groovy.parser.antlr4.GroovyParser.NamePartContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.NamedPropertyArgsContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.NewPrmrAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.NonWildcardTypeArgumentsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.NullLiteralAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.OriginalForControlContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.PRIVATE;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.PackageDeclarationContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ParExpressionContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.PathElementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.PathExpressionContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.PostfixExpressionContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.PowerExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.PrimitiveTypeContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.QualifiedClassNameContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.QualifiedClassNameListContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.QualifiedNameContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.QualifiedNameElementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.QualifiedStandardClassNameContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_FULL;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_LEFT;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.RANGE_EXCLUSIVE_RIGHT;
+import static org.apache.groovy.parser.antlr4.GroovyParser.RANGE_INCLUSIVE;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ReferenceTypeContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.RegexExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.RelationalExprAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ResourceContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ResourceListContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ResourcesContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ReturnStmtAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ReturnTypeContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.SAFE_INDEX;
+import static org.apache.groovy.parser.antlr4.GroovyParser.SEALED;
+import static org.apache.groovy.parser.antlr4.GroovyParser.STATIC;
+import static org.apache.groovy.parser.antlr4.GroovyParser.SUB;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ScriptStatementsContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ShiftExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.StandardLambdaExpressionContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.StandardLambdaParametersContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.StatementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.StringLiteralContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.SuperPrmrAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.SwitchBlockStatementExpressionGroupContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.SwitchBlockStatementGroupContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.SwitchExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.SwitchExpressionContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.SwitchExpressionLabelContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.SwitchLabelContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.SwitchStatementContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.SynchronizedStmtAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.ThisFormalParameterContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ThisPrmrAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.ThrowStmtAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.TryCatchStatementContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.TypeArgumentsOrDiamondContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.TypeBoundContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.TypeContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.TypeDeclarationContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.TypeListContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.TypeNamePairContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.TypeNamePairsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.TypeParameterContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.TypeParametersContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.UnaryAddExprAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.UnaryNotExprAltContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.VAR;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclarationContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorIdContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableDeclaratorsContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableInitializerContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableModifierContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableModifiersContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableModifiersOptContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.VariableNamesContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.WhileStmtAltContext;
+import static
org.apache.groovy.parser.antlr4.GroovyParser.YieldStatementContext;
+import static org.apache.groovy.parser.antlr4.GroovyParser.YieldStmtAltContext;
Review Comment:
The massive expansion of individual static imports (158-362) makes the code
harder to maintain. Consider using a wildcard import `import static
org.apache.groovy.parser.antlr4.GroovyParser.*;` instead, which is already the
pattern used in the original code.
```suggestion
import static org.apache.groovy.parser.antlr4.GroovyParser.*;
```
> Support async/await like ES7
> ----------------------------
>
> Key: GROOVY-9381
> URL: https://issues.apache.org/jira/browse/GROOVY-9381
> Project: Groovy
> Issue Type: New Feature
> Reporter: Daniel Sun
> Priority: Major
>
> Here is an example to show proposed syntax and backend API(Java's
> {{CompletableFuture}} or GPars's {{{}Promise{}}}), but I think it's better
> for Groovy to have its own {{Promise}} to decouple with Java API because
> async/await as a language feature should be as stable as possible.
> {{async}} will generate the {{Awaitable}} instance such as Groovy {{Promise}}
> implementing the {{Awaitable}} interface, and {{await}} can wait for any
> {{Awaitable}} instance to complete and unwrap it for the result.
> {code:java}
> /**
> * 1. An async function that simulates a network API call.
> * The 'async' keyword implies it runs asynchronously without blocking.
> */
> async fetchUserData(userId) {
> println "Starting to fetch data for user ${userId}..."
>
> // Simulate a 1-second network delay.
> Thread.sleep(1000)
>
> println "Fetch successful!"
> // The 'async' function implicitly returns a "CompletableFuture" or
> "Promise" containing this value.
> return [userId: userId, name: 'Daniel']
> }
> /**
> * 2. An async function that uses 'await' to consume the result.
> */
> async processUserData() {
> println "Process started, preparing to fetch user data..."
>
> try {
> // 'await' pauses this function until fetchUserData completes
> // and returns the final result directly.
> def user = await fetchUserData(1)
>
> println "Data received: ${user}"
> return "Processing complete for ${user.name}."
>
> } catch (Exception e) {
> return "An error occurred: ${e.message}"
> }
> }
> // --- Execution ---
> println "Script starting..."
> // Kick off the entire asynchronous process.
> def future = processUserData()
> // This line executes immediately, proving the process is non-blocking.
> println "Script continues to run while user data is being fetched in the
> background..."
> def result = future.get()
> println "Script finished: ${result}"
> {code}
> Use async/await with closure or lambda expression:
> {code}
> // use closure
> def c = async {
> println "Process started, preparing to fetch user data..."
>
> try {
> // 'await' pauses this function until fetchUserData completes
> // and returns the final result directly.
> def user = await fetchUserData(1)
>
> println "Data received: ${user}"
> return "Processing complete for ${user.name}."
>
> } catch (Exception e) {
> return "An error occurred: ${e.message}"
> }
> }
> def future = c()
> {code}
> {code}
> // use lambda expression
> def c = async () -> {
> println "Process started, preparing to fetch user data..."
>
> try {
> // 'await' pauses this function until fetchUserData completes
> // and returns the final result directly.
> def user = await fetchUserData(1)
>
> println "Data received: ${user}"
> return "Processing complete for ${user.name}."
>
> } catch (Exception e) {
> return "An error occurred: ${e.message}"
> }
> }
> def future = c()
> {code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)