In my app I have a supervisor which creates some workers. Each of these workers needs two QueueClients instances (with different configurations and different instances between workers). I'm new to guice and I'm having problems to inject these dependencies in child actors.
This is my worker class:
object LegacyConsumer {
trait Factory {
def apply(): Actor
}
}
class LegacyConsumer @Inject()(
eventsClient: QueueClient,
deadLetterClient: QueueClient
) extends Actor with ActorLogging {
override def preStart(): Unit = {
log.error("prestart")
log.error(eventsClient.toString)
}
def receive: PartialFunction[Any, Unit] = {
case _ =>
log.error("received message consumer")
}
}
As you can see I need the two QueueClients for construction:
trait QueueClient {
...
def numMessages: Int
}
class SqsClient @Inject()(name: String, key: String, secret: String, zone: String) extends Logging with QueueClient {
...
}
This is how I trying to create my workers
class LegacyConsumerSupervisor @Inject()(
consumerFactory: LegacyConsumer.Factory,
@Named("numWorkers") workers: Int
)
extends Actor with ActorLogging with InjectedActorSupport {
override def preStart(): Unit = {
(1 to workers).foreach { workerNumber =>
val key = s"WORKER-$workerNumber"
injectedChild(consumerFactory(), key, _.withDispatcher("akka.legacy-consumer-dispatcher"))
}
}
And finally this is how my bindings look like
class ChatModule extends AbstractModule with ScalaModule with AkkaGuiceSupport{
override def configure() {
bind[Actor].annotatedWith(Names.named(LegacyConsumerSupervisor.name)).to[LegacyConsumerSupervisor]
bind(classOf[Int])
.annotatedWith(Names named "numWorkers")
.toInstance(ConfigurationHelper.getInt("chat.legacy.num-workers"))
bindActorFactory[LegacyConsumer, LegacyConsumer.Factory]
bind(classOf[QueueClient])
// .annotatedWith(Names named "legacyEventsClient")
.toInstance(
new SqsClient(
ConfigurationHelper.getString("chat.legacy.events.name"),
ConfigurationHelper.getString("chat.legacy.events.key"),
ConfigurationHelper.getString("chat.legacy.events.secret"),
ConfigurationHelper.getString("chat.legacy.events.region")
)
)
bind(classOf[QueueClient])
// .annotatedWith(Names named "legacyDeadLetterClient")
.toInstance(
new SqsClient(
ConfigurationHelper.getString("chat.legacy.dead-letter.name"),
ConfigurationHelper.getString("chat.legacy.dead-letter.key"),
ConfigurationHelper.getString("chat.legacy.dead-letter.secret"),
ConfigurationHelper.getString("chat.legacy.dead-letter.region")
)
)
}
}
How can I inject different instances of queue clients into each worker? All legacyEventsClients and legacyDeadLetterClients have the same config (based on typesafe config). Does the solution something related with Assisted injection?
The error I'm getting now:
A binding to ...QueueClient was already configured at ...configure(ChatModule.scala:29). at ...configure(ChatModule.scala:40)
So I think the problem is about try to inject the same binding twice to different instances... I tried to do with named parameters but then the same instance of client is injected to each LegacyConsumer
Regards