I'm facing non-deterministic trouble with PrivateModules and Multibindings.
My architecture is that I have Controller-Service pairs which communicate using a MessageQueue. Each Service is running in its own thread and only the Controller which is paired with it can send messages to it. All Controllers are placed into a ControllerHub (which is also itself a Service running in its own thread), which broadcasts messages to all Controllers. To prevent anyone else from getting direct access to the Controllers and Services, I've implemented them as PrivateModules like this: Infrastructure: http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/modules/ServiceInstallerModule.java http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/services/ServiceModule.java Modules: http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/modules/CommonModules.java http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/modules/ControllerModule.java http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/modules/AuthenticatorModule.java http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/modules/NetworkModule.java The class which gets all the ServiceRegistrations and starts them in their own threads: http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/services/ServiceStarter.java http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/services/ServiceRunner.java My problem is that even though I bind the message queue interfaces inside the private modules (http://github.com/orfjackal/dimdwarf/blob/ ctrl-bug/dimdwarf-core/src/main/java/net/orfjackal/dimdwarf/services/ ServiceModule.java#L72-76), sometimes non-deterministically the controllers from two different modules both receive the same message queue instance. Here are the controllers. I've made them print in their constructors the MessageSender instance that is injected. It will print either "MessageQueue(Network)" or "MessageQueue(Authenticator)" depending on which module owns that message queue. http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/scala/net/orfjackal/dimdwarf/auth/AuthenticatorController.scala http://github.com/orfjackal/dimdwarf/blob/ctrl-bug/dimdwarf-core/src/main/scala/net/orfjackal/dimdwarf/net/NetworkController.scala Here is the output from a passing test run. Notice that now AuthenticatorController and NetworkController both got their own MessageQueue instances injected. They print "AuthenticatorController: MessageQueue(Authenticator)" and "NetworkController: MessageQueue(Network)" respectively. 00:57:42.592 [main] INFO net.orfjackal.dimdwarf.server.Main - Dimdwarf 0.1.0-SNAPSHOT starting up 00:57:43.103 [main] INFO net.orfjackal.dimdwarf.server.Main - Modules loaded 00:57:43.113 [main] INFO net.orfjackal.dimdwarf.server.Main - Bootstrapper created AuthenticatorModule.service: MessageQueue(Authenticator) 00:57:43.117 [Authenticator] DEBUG n.o.d.services.ServiceMessageLoop - START: class net.orfjackal.dimdwarf.auth.AuthenticatorService NetworkModule.service: MessageQueue(Network) 00:57:43.120 [Network] DEBUG n.o.d.services.ServiceMessageLoop - START: class net.orfjackal.dimdwarf.net.NetworkService AuthenticatorController: MessageQueue(Authenticator) 00:57:43.238 [Controller] INFO n.o.d.modules.ControllerModule - Registering controller "Authenticator" of type net.orfjackal.dimdwarf.auth.AuthenticatorController NetworkController: MessageQueue(Network) 00:57:43.239 [Controller] INFO n.o.d.modules.ControllerModule - Registering controller "Network" of type net.orfjackal.dimdwarf.net.NetworkController 00:57:43.239 [Controller] DEBUG n.o.d.services.ServiceMessageLoop - START: class net.orfjackal.dimdwarf.controller.ControllerHub 00:57:43.241 [Network] INFO n.o.dimdwarf.net.NetworkService - Begin listening on port 56536 00:57:43.247 [main] INFO net.orfjackal.dimdwarf.server.Main - Server started 00:57:43.339 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - CREATED 00:57:43.339 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - OPENED 00:57:43.386 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - RECEIVED: HeapBuffer[pos=0 lim=26 cap=2048: 00 18 10 05 00 04 75 73 65 72 00 0E 77 72 6F 6E...] 00:57:43.386 [NioProcessor-1] DEBUG o.a.m.f.codec.ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1 00:57:43.395 [NioProcessor-1] DEBUG n.o.d.net.SimpleSgsProtocolIoHandler - RECEIVED: LoginRequest() 00:57:43.395 [Controller] DEBUG n.o.d.services.ServiceMessageLoop - PROCESS: LoginRequest() MessageQueue(Authenticator) 00:57:43.398 [Authenticator] DEBUG n.o.d.services.ServiceMessageLoop - PROCESS: IsUserAuthenticated() 00:57:43.399 [Controller] DEBUG n.o.d.services.ServiceMessageLoop - PROCESS: NoUserIsNotAuthenticated() 00:57:43.400 [Network] DEBUG n.o.d.services.ServiceMessageLoop - PROCESS: LoginFailure() 00:57:43.404 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - SENT: HeapBuffer[pos=0 lim=5 cap=5: 00 03 12 00 00] 00:57:43.404 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty] 00:57:43.406 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - CLOSED Here is the output from a failing test run, without any source code modifications. Notice that now both AuthenticatorController and NetworkController print that they got the same MessageQueue instance "MessageQueue(Network)" injected! 00:53:44.347 [main] INFO net.orfjackal.dimdwarf.server.Main - Dimdwarf 0.1.0-SNAPSHOT starting up 00:53:44.893 [main] INFO net.orfjackal.dimdwarf.server.Main - Modules loaded 00:53:44.903 [main] INFO net.orfjackal.dimdwarf.server.Main - Bootstrapper created AuthenticatorModule.service: MessageQueue(Authenticator) NetworkModule.service: MessageQueue(Network) 00:53:44.927 [Authenticator] DEBUG n.o.d.services.ServiceMessageLoop - START: class net.orfjackal.dimdwarf.auth.AuthenticatorService 00:53:44.928 [Network] DEBUG n.o.d.services.ServiceMessageLoop - START: class net.orfjackal.dimdwarf.net.NetworkService AuthenticatorController: MessageQueue(Network) NetworkController: MessageQueue(Network) 00:53:45.037 [Controller] INFO n.o.d.modules.ControllerModule - Registering controller "Network" of type net.orfjackal.dimdwarf.net.NetworkController 00:53:45.037 [Controller] INFO n.o.d.modules.ControllerModule - Registering controller "Authenticator" of type net.orfjackal.dimdwarf.auth.AuthenticatorController 00:53:45.038 [Controller] DEBUG n.o.d.services.ServiceMessageLoop - START: class net.orfjackal.dimdwarf.controller.ControllerHub 00:53:45.051 [Network] INFO n.o.dimdwarf.net.NetworkService - Begin listening on port 56379 00:53:45.058 [main] INFO net.orfjackal.dimdwarf.server.Main - Server started 00:53:45.151 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - CREATED 00:53:45.151 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - OPENED 00:53:45.201 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - RECEIVED: HeapBuffer[pos=0 lim=26 cap=2048: 00 18 10 05 00 04 75 73 65 72 00 0E 77 72 6F 6E...] 00:53:45.201 [NioProcessor-1] DEBUG o.a.m.f.codec.ProtocolCodecFilter - Processing a MESSAGE_RECEIVED for session 1 00:53:45.211 [NioProcessor-1] DEBUG n.o.d.net.SimpleSgsProtocolIoHandler - RECEIVED: LoginRequest() 00:53:45.212 [Controller] DEBUG n.o.d.services.ServiceMessageLoop - PROCESS: LoginRequest() MessageQueue(Network) 00:53:45.216 [Network] DEBUG n.o.d.services.ServiceMessageLoop - PROCESS: IsUserAuthenticated() 00:53:45.222 [NioProcessor-1] INFO o.a.m.filter.logging.LoggingFilter - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty] Do you have any ideas where the problem could be? Have I understood incorrectly that how PrivateModules work and is my plugin system flawed? Could it be related that the controllers from all PrivateModules run in the same thread-local scope ControllerScoped? Can it affect this, that the services are controllers are all injected concurrently in different threads? Can it be related that the ControllerModule, which is itself a ServiceModule (which extends PrivateModule), uses the Set<ControllerRegistration> multibinding from all other ServiceModules? P.S. In case the logs in this message are hard to read due to line wrapping by the mailing list, here is a copy of the same message: http://www.orfjackal.net/temp/guice_message_2010-08-27.txt -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
