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

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-7040-75606f1f28426b79487bde4dcd3296cef60141dc
in repository https://gitbox.apache.org/repos/asf/texera.git

commit 0834f25d605a611ed9130fd05c7a7e6f702254d1
Author: Xinyuan Lin <[email protected]>
AuthorDate: Wed Jul 29 17:01:17 2026 -0700

    refactor(config): replace the hand-rolled AuthConfig secret lock with lazy 
val (#7040)
    
    ### What changes were proposed in this PR?
    
    `AuthConfig.jwtSecretKey` hand-rolls a double-checked-locking lazy
    initializer — a `@volatile var`, a null sentinel and a `synchronized`
    block — to compute one value once. Scala's `lazy val` is that exact
    pattern, generated by the compiler.
    
    ```scala
    // before
    @volatile private var secretKey: String = _
    
    def jwtSecretKey: String = {
      synchronized {
        if (secretKey == null) {
          secretKey = conf.getString("auth.jwt.256-bit-secret").toLowerCase() 
match {
            case "random" => getRandomHexString
            case key      => key
          }
        }
      }
      secretKey
    }
    
    // after
    lazy val jwtSecretKey: String = 
conf.getString("auth.jwt.256-bit-secret").toLowerCase() match {
      case "random" => getRandomHexString
      case key      => key
    }
    ```
    
    Behaviour is preserved on every axis I checked:
    
    | | hand-rolled | `lazy val` |
    | --- | --- | --- |
    | initialized at most once | yes | yes |
    | safe under concurrent first access | yes (`synchronized`) | yes
    (compiler-generated DCL) |
    | safe publication of the result | yes (`@volatile`) | yes |
    | behaviour if the initializer throws | leaves the field null, retries
    next call | initialized bit not set, retries next call |
    | call-site shape | `AuthConfig.jwtSecretKey` | unchanged |
    
    The single caller, `JwtAuth.scala:35` (`final val TOKEN_SECRET =
    AuthConfig.jwtSecretKey`), needs no change — `def` and `lazy val` are
    indistinguishable at the call site. `getRandomHexString` stays a private
    `def`, so `AuthConfigSpec`'s reflective lookup of it still resolves.
    
    −14 lines, +6.
    
    ### Any related issues, documentation, discussions?
    
    Closes #7039
    
    ### How was this PR tested?
    
    Existing tests only — this PR adds none, since it is a
    behaviour-preserving rewrite already covered by `AuthConfigSpec` (which
    pins both the configured-secret path and that the value is memoized
    across calls).
    
    Locally, from the repo root with Java 17:
    
    - `sbt "scalafixAll --check"` — clean.
    - `sbt scalafmtCheckAll` — clean.
    - `sbt "Config/testOnly *AuthConfigSpec"` — 3 tests, all pass,
    unmodified.
    
    The whole-repo scalafix/scalafmt run also compiles `common/auth`, so the
    `JwtAuth` call site is covered.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Claude Opus 5)
    
    Co-authored-by: Yicong Huang 
<[email protected]>
---
 .../org/apache/texera/common/config/AuthConfig.scala | 20 ++++++--------------
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git 
a/common/config/src/main/scala/org/apache/texera/common/config/AuthConfig.scala 
b/common/config/src/main/scala/org/apache/texera/common/config/AuthConfig.scala
index 43e1409ecd..abda5dff3d 100644
--- 
a/common/config/src/main/scala/org/apache/texera/common/config/AuthConfig.scala
+++ 
b/common/config/src/main/scala/org/apache/texera/common/config/AuthConfig.scala
@@ -28,20 +28,12 @@ object AuthConfig {
   // Read jwt Expiration time in minutes
   final val jwtExpirationMinutes: Int = 
conf.getInt("auth.jwt.expiration-in-minutes")
 
-  // For storing the generated/configured secret
-  @volatile private var secretKey: String = _
-
-  // Read JWT secret key with support for random generation
-  def jwtSecretKey: String = {
-    synchronized {
-      if (secretKey == null) {
-        secretKey = conf.getString("auth.jwt.256-bit-secret").toLowerCase() 
match {
-          case "random" => getRandomHexString
-          case key      => key
-        }
-      }
-    }
-    secretKey
+  // Read JWT secret key with support for random generation.
+  // `lazy val` already compiles to a thread-safe, initialize-once accessor, 
so it
+  // replaces the hand-rolled @volatile + synchronized double-checked lock.
+  lazy val jwtSecretKey: String = 
conf.getString("auth.jwt.256-bit-secret").toLowerCase() match {
+    case "random" => getRandomHexString
+    case key      => key
   }
 
   private def getRandomHexString: String = {

Reply via email to