Packages

o

com.digitalasset.canton

SynchronizedFuture

object SynchronizedFuture extends WartTraverser

When a synchronized block returns a scala.concurrent.Future, then the synchronization typically does not extend to the computations performed inside the future. This often hides a concurrency bug that is hard to spot during review because the computation's code is lexically inside the synchronized block and it may not be obvious that scala.concurrent.Futures are in play.

For example, synchronized blocks are often used to read and update the state of an object atomically. When the update operation involves a scala.concurrent.Future like below, then the write to the state is actually not guarded by the synchronized call and the update is not atomic.

synchronized {
  val x = this.atomicRef.get()
  futureComputation(x).map { y =>
    this.atomicRef.set(y)
    y
  }
}

The proper approach in the above example is to use a semaphore instead of a synchronized block.

blocking { this.semaphore.acquire() }
val x = this.atomicRef.get()
futureComputation(x).map { y =>
  this.atomicRef.set(y)
  y
}.thereafter { _ => this.semaphore.release() }

If the synchronization intentionally does not have to extend over the scala.concurrent.Future computation, it usually helps with readability to move the future out of the synchronized block. For example,

blocking(synchronized {
  val x = criticalSection()
  Future { nonCriticalSection(x) }
})

should be written as follows:

val x = blocking(synchronized { criticalSection() })
Future { nonCriticalSection(x) }

There are cases where the synchronized block is supposed to return a scala.concurrent.Future, for example when dealing with the promise of a future. In such a case, the warning should simply be suppressed locally.

Linear Supertypes
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. SynchronizedFuture
  2. WartTraverser
  3. AnyRef
  4. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##: Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. def apply(u: WartUniverse): Traverser
    Definition Classes
    SynchronizedFuture → WartTraverser
  5. def asAnnotationMacro(c: Context)(annottees: scala.reflect.macros.blackbox.Context.Expr[Any]*): scala.reflect.macros.blackbox.Context.Expr[Any]
    Definition Classes
    WartTraverser
  6. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  7. def asMacro(c: Context)(expr: scala.reflect.macros.blackbox.Context.Expr[Any]): scala.reflect.macros.blackbox.Context.Expr[Any]
    Definition Classes
    WartTraverser
  8. lazy val className: String
    Definition Classes
    WartTraverser
  9. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @IntrinsicCandidate() @native()
  10. def compose(o: WartTraverser): WartTraverser
    Definition Classes
    WartTraverser
  11. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  12. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  13. def error(u: WartUniverse)(pos: scala.reflect.api.Universe.Position, message: String): Unit
    Definition Classes
    WartTraverser
  14. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @IntrinsicCandidate() @native()
  15. def hasTypeAscription(u: WartUniverse)(tree: scala.reflect.api.Universe.ValOrDefDef): Boolean
    Definition Classes
    WartTraverser
  16. def hasWartAnnotation(u: WartUniverse)(tree: scala.reflect.api.Universe.Tree): Boolean
    Definition Classes
    WartTraverser
  17. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @IntrinsicCandidate() @native()
  18. def isAnonymousFunctionName(u: WartUniverse)(t: scala.reflect.api.Universe.TypeName): Boolean
    Definition Classes
    WartTraverser
  19. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  20. def isPrimitive(u: WartUniverse)(t: scala.reflect.api.Universe.Type): Boolean
    Definition Classes
    WartTraverser
  21. def isPrivate(u: WartUniverse)(t: scala.reflect.api.Universe.ValOrDefDef): Boolean
    Definition Classes
    WartTraverser
  22. def isPublic(u: WartUniverse)(t: scala.reflect.api.Universe.ValOrDefDef): Boolean
    Definition Classes
    WartTraverser
  23. def isSynthetic(u: WartUniverse)(t: scala.reflect.api.Universe.Tree): Boolean
    Definition Classes
    WartTraverser
  24. def isSyntheticPartialFunction(u: WartUniverse)(tree: scala.reflect.api.Universe.Tree): Boolean
    Definition Classes
    WartTraverser
  25. def isWartAnnotation(u: WartUniverse)(a: scala.reflect.api.Universe.Annotation): Boolean
    Definition Classes
    WartTraverser
  26. val messageSynchronized: String
  27. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  28. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @IntrinsicCandidate() @native()
  29. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @IntrinsicCandidate() @native()
  30. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  31. def toString(): String
    Definition Classes
    AnyRef → Any
  32. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  33. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()
  34. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  35. def warning(u: WartUniverse)(pos: scala.reflect.api.Universe.Position, message: String): Unit
    Definition Classes
    WartTraverser
  36. lazy val wartName: String
    Definition Classes
    WartTraverser
  37. def wasInferred(u: WartUniverse)(t: scala.reflect.api.Universe.TypeTree): Boolean
    Definition Classes
    WartTraverser

Deprecated Value Members

  1. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable]) @Deprecated
    Deprecated

    (Since version 9)

Inherited from WartTraverser

Inherited from AnyRef

Inherited from Any

Ungrouped