Skip to content

Commit

Permalink
Build EagerSingleton just after Session instantiation
Browse files Browse the repository at this point in the history
  • Loading branch information
Lewuathe committed Aug 19, 2016
1 parent 067b13a commit 15208dd
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
4 changes: 3 additions & 1 deletion wvlet-inject/src/main/scala/wvlet/inject/Inject.scala
Expand Up @@ -121,7 +121,9 @@ class Inject extends LogSupport {
}
val keyIndex : Map[ObjectType, Int] = originalBindings.map(_.from).zipWithIndex.map(x => x._1 -> x._2).toMap
val sortedBindings = effectiveBindings.toSeq.sortBy(x => keyIndex(x.from))
new SessionImpl(sortedBindings, listener.result())
val s = new SessionImpl(sortedBindings, listener.result())
s.init()
s
}

def addBinding(b: Binding): Inject = {
Expand Down
15 changes: 9 additions & 6 deletions wvlet-inject/src/main/scala/wvlet/inject/SessionImpl.scala
Expand Up @@ -33,12 +33,14 @@ private[inject] class SessionImpl(binding: Seq[Binding], listener: Seq[SessionLi

private lazy val singletonHolder: collection.mutable.Map[ObjectType, Any] = new ConcurrentHashMap[ObjectType, Any]()

// Initialize eager singleton
binding.collect {
case s@SingletonBinding(from, to, eager) if eager =>
singletonHolder.getOrElseUpdate(to, buildInstance(to, Set(to)))
case InstanceBinding(from, obj) =>
registerInjectee(from, obj)
private[inject] def init() = {
// Initialize eager singleton
binding.collect {
case s@SingletonBinding(from, to, eager) if eager =>
singletonHolder.getOrElseUpdate(to, buildInstance(to, Set(to)))
case InstanceBinding(from, obj) =>
registerInjectee(from, obj)
}
}

def get[A](implicit ev: ru.WeakTypeTag[A]): A = {
Expand Down Expand Up @@ -89,6 +91,7 @@ private[inject] class SessionImpl(binding: Seq[Binding], listener: Seq[SessionLi
newInstance(p.valueType, seen)
}
trace(s"Build a new instance for ${t}")
// Add TODO: enable injecting Session to concrete classes
val obj = schema.constructor.newInstance(args)
registerInjectee(t, obj)
case None =>
Expand Down
19 changes: 18 additions & 1 deletion wvlet-inject/src/test/scala/wvlet/inject/InjectTest.scala
Expand Up @@ -16,7 +16,7 @@ package wvlet.inject
import java.io.PrintStream
import java.util.concurrent.atomic.AtomicInteger

import wvlet.log.LogSupport
import wvlet.log.{LogLevel, LogSupport}
import wvlet.obj.ObjectType
import wvlet.obj.tag.@@
import wvlet.test.WvletSpec
Expand Down Expand Up @@ -131,6 +131,12 @@ object ServiceMixinExample {
val initializedTime = System.nanoTime()
}

trait EagerSingletonWithInject extends LogSupport {
info("initialized")
val heavy = inject[HeavyObject]
val initializedTime = System.nanoTime()
}

class ClassWithContext(val c: Session) extends FortunePrinterMixin with LogSupport {
//info(s"context ${c}") // we should access context since Scala will remove private field, which is never used
}
Expand Down Expand Up @@ -217,6 +223,17 @@ class InjectTest extends WvletSpec {
s.initializedTime should be < current
}

"create single with inject eagerly" in {
val start = System.nanoTime()
val h = new Inject
h.bind[EagerSingletonWithInject].toEagerSingleton
val c = h.newSession
val current = System.nanoTime()
val s = c.get[EagerSingletonWithInject]

s.initializedTime should be > start
s.initializedTime should be < current
}

"found cyclic dependencies" in {
val c = new Inject().newSession
Expand Down

0 comments on commit 15208dd

Please sign in to comment.