Skip to content

Instantly share code, notes, and snippets.

@dwalend
Last active March 2, 2017 15:13
Show Gist options
  • Select an option

  • Save dwalend/5a193daa24af8dbfbdc5 to your computer and use it in GitHub Desktop.

Select an option

Save dwalend/5a193daa24af8dbfbdc5 to your computer and use it in GitHub Desktop.

Revisions

  1. dwalend revised this gist Jun 22, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ExampeConfigSource.scala
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    *
    * @author dwalend
    */
    object ExampeConfigSource {
    object ExampleConfigSource {
    //load from application.conf and the usual TypeSafe Config chain
    val atomicConfig = new AtomicConfigSource(ConfigFactory.load())

  2. dwalend revised this gist Jun 16, 2015. 2 changed files with 9 additions and 5 deletions.
    6 changes: 4 additions & 2 deletions AtomicConfigSource.scala
    Original file line number Diff line number Diff line change
    @@ -38,11 +38,13 @@ class AtomicConfigSource(baseConfig:Config) {
    tryT match {
    case Success(t) => {
    if(ok) t
    else throw new IllegalStateException(s"Expected config from ${blockConfig.origin()} to be from ${atomicConfigRef.get().origin()} instead.")
    else throw new IllegalStateException(
    s"Expected config from ${blockConfig.origin()} to be from ${atomicConfigRef.get().origin()} instead.")
    }
    case Failure(x) => {
    if(ok) throw x
    else throw new IllegalStateException(s"Throwable in block and expected config from ${blockConfig.origin()} to be from ${atomicConfigRef.get().origin()} instead.",x)
    else throw new IllegalStateException(
    s"Throwable in block and expected config from ${blockConfig.origin()} to be from ${atomicConfigRef.get().origin()} instead.",x)
    }
    }
    }
    8 changes: 5 additions & 3 deletions AtomicConfigSourceExample.scala → ExampeConfigSource.scala
    Original file line number Diff line number Diff line change
    @@ -3,10 +3,12 @@
    *
    * @author dwalend
    */
    object AtomicConfigSourceExample {
    val atomicConfig = new AtomicConfigSource(ConfigFactory.load()) //load from application.conf and the usual TypeSafe Config chain
    object ExampeConfigSource {
    //load from application.conf and the usual TypeSafe Config chain
    val atomicConfig = new AtomicConfigSource(ConfigFactory.load())

    def config:Config = atomicConfig.config

    def configForBlock[T](key:String,value:AnyRef,origin:String)(block: => T):T = atomicConfig.configForBlock(key,value,origin)(block)
    def configForBlock[T](key:String,value:AnyRef,origin:String)(block: => T):T =
    atomicConfig.configForBlock(key,value,origin)(block)
    }
  3. dwalend renamed this gist Jun 15, 2015. 1 changed file with 0 additions and 0 deletions.
  4. dwalend created this gist Jun 15, 2015.
    12 changes: 12 additions & 0 deletions AtomicConfigSExample.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    /**
    * A little object to let you reach your config from anywhere.
    *
    * @author dwalend
    */
    object AtomicConfigSourceExample {
    val atomicConfig = new AtomicConfigSource(ConfigFactory.load()) //load from application.conf and the usual TypeSafe Config chain

    def config:Config = atomicConfig.config

    def configForBlock[T](key:String,value:AnyRef,origin:String)(block: => T):T = atomicConfig.configForBlock(key,value,origin)(block)
    }
    49 changes: 49 additions & 0 deletions AtomicConfigSource.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    import java.util.concurrent.atomic.AtomicReference
    import scala.util.{Failure, Success, Try}
    import com.typesafe.config.{Config, ConfigFactory}
    /**
    Use to tweak a Config without clearing and reloading a new config (for testing).
    @author dwalend
    */
    class AtomicConfigSource(baseConfig:Config) {
    val atomicConfigRef = new AtomicReference[Config](ConfigFactory.empty())

    /**
    * Get the Atomic Config. Be sure to use defs for all config values that might be changed.
    */
    def config:Config = atomicConfigRef.get().withFallback(baseConfig)

    /**
    * Use the config in a block of code.
    */
    def configForBlock[T](key:String,value:AnyRef,origin:String)(block: => T):T = {
    val configPairs = Map(key -> value)
    configForBlock(configPairs,origin)(block)
    }

    /**
    * Use the config in a block of code.
    */
    def configForBlock[T](configPairs:Map[String, _ <: AnyRef],origin:String)(block: => T):T = {
    import scala.collection.JavaConverters.mapAsJavaMapConverter

    val configPairsJava:java.util.Map[String, _ <: AnyRef] = configPairs.asJava
    val blockConfig:Config = ConfigFactory.parseMap(configPairsJava,origin)
    val originalConfig:Config = atomicConfigRef.getAndSet(blockConfig)
    val tryT:Try[T] = Try(block)

    val ok = atomicConfigRef.compareAndSet(blockConfig,originalConfig)

    tryT match {
    case Success(t) => {
    if(ok) t
    else throw new IllegalStateException(s"Expected config from ${blockConfig.origin()} to be from ${atomicConfigRef.get().origin()} instead.")
    }
    case Failure(x) => {
    if(ok) throw x
    else throw new IllegalStateException(s"Throwable in block and expected config from ${blockConfig.origin()} to be from ${atomicConfigRef.get().origin()} instead.",x)
    }
    }
    }
    }