All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kamon.package.scala Maven / Gradle / Ivy

There is a newer version: 2.7.5
Show newest version
/*
 * Copyright 2013-2021 The Kamon Project 
 *
 * Licensed 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.
 */

import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.{Executors, ScheduledExecutorService, ScheduledThreadPoolExecutor, ThreadFactory, TimeUnit}
import com.typesafe.config.{Config, ConfigUtil}

import scala.collection.concurrent.TrieMap

package object kamon {

  def newScheduledThreadPool(corePoolSize: Int, threadFactory: ThreadFactory): ScheduledExecutorService = {
    val tp = new ScheduledThreadPoolExecutor(corePoolSize, threadFactory)
    val timeout = 5000
    // Call in this order or it throws!
    tp.setKeepAliveTime(timeout, TimeUnit.MILLISECONDS)
    tp.allowCoreThreadTimeOut(true)

    tp.setRemoveOnCancelPolicy(true)

    tp
  }

  /**
    * Creates a thread factory that assigns the specified name to all created Threads.
    */
  def threadFactory(name: String, daemon: Boolean = false): ThreadFactory =
    new ThreadFactory {
      val defaultFactory = Executors.defaultThreadFactory()

      override def newThread(r: Runnable): Thread = {
        val thread = defaultFactory.newThread(r)
        thread.setName(name)
        thread.setDaemon(daemon)
        thread
      }
    }

  def numberedThreadFactory(name: String, daemon: Boolean = false): ThreadFactory =
    new ThreadFactory {
      val count = new AtomicLong()
      val defaultFactory = Executors.defaultThreadFactory()

      override def newThread(r: Runnable): Thread = {
        val thread = defaultFactory.newThread(r)
        thread.setName(name + "-" + count.incrementAndGet().toString)
        thread.setDaemon(daemon)
        thread
      }
    }


  /**
    *  Workaround to the non thread-safe [scala.collection.concurrent.TrieMap#getOrElseUpdate()] method. More details on
    *  why this is necessary can be found at [[https://issues.scala-lang.org/browse/SI-7943]].
    */
  implicit class AtomicGetOrElseUpdateOnTrieMap[K, V](val trieMap: TrieMap[K, V]) extends AnyVal {

    def atomicGetOrElseUpdate(key: K, op: => V): V =
      atomicGetOrElseUpdate(key, op, { _: V => () }, { _: V => () })

    def atomicGetOrElseUpdate(key: K, op: => V, cleanup: V => Unit, init: V => Unit): V =
      trieMap.get(key) match {
        case Some(v) => v
        case None =>
          val d = op
          trieMap.putIfAbsent(key, d) match {
            case Some(oldValue) =>
              // If there was an old value then `d` was never added
              // and thus need to be cleanup.
              cleanup(d)
              oldValue

            case None =>
              init(d)
              d
          }
      }
  }

  implicit class UtilsOnConfig(val config: Config) extends AnyVal {
    import scala.collection.JavaConverters._

    def topLevelKeys: Set[String] =
      config.root().entrySet().asScala.map(_.getKey).toSet

    def configurations: Map[String, Config] = {
      topLevelKeys
        .map(entry => (entry, config.getConfig(ConfigUtil.joinPath(entry))))
        .toMap
    }

    def pairs: Map[String, String] = {
      config.root().entrySet().asScala.map { entry =>
        (entry.getKey, entry.getValue.unwrapped().asInstanceOf[String])
      }.toMap
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy