5 Replies Latest reply on Nov 24, 2016 11:00 AM by mbarkley

    lazy singleton support

    marius.gerwinn

      Hi,

       

      dependency injection with errai is working for us much better now than our previous implementation with google-gin.

       

      Anyhow we kind of running into the same problems since our app is getting really large. One issue is the startup time of the app, both in development and in production.

      When using gin we could achieve a big performance/time boost wrapping all instances with a provider and only access the actual instances when eventually needed.

      This was no problem since gin supports lazy singletons.

       

      Errai currently doesn’t support lazy singletons. So each time our app starts there are a lot of instances that are created even if their first usage is at a much later time.

      Also code splitting (@LoadAsync) has no effect to those classes, since they are created upfront.

      On the other hand we see the requirement for non lazy singletons when it comes to @Producers, @IOCProviders.

       

      So lets talk about some solutions:

      1. Make @Singleton lazy by default. As a counterpart @EntryPoint should be non lazy and created upfront. Producers and IOC providers that should be available directly can than be annotated with @EntryPoint.

       

      2. An other solution could be qualifying the lazy singletons. So add a new annotation @LazySingleton and add it to any singleton that should be lazy instantiated

       

       

      Whats your opinion?

       

       

      P.S.: After digging a little bit into the ioc logic we probably found the source where singletons are created.

      At the end of the BootstrapperImpl file there are addBean(….) calls for a lot of classes. In the case of a lazy singleton this should be prevented.

      So maybe implementing lazy singletons wouldn’t be that difficult, since we only need to remove the addBean(...) statement.

        • 1. Re: lazy singleton support
          csa

          Hi Marius,

           

          Yes, I think having this as a feature would be nice. I'd prefer having an extra annotation @LazySingleton as you suggested. However, simply skipping the addBean() call won't do it because this call just registers the bean with the BeanManager. We would have to find a way to delay the call to getInstance() in the Bootstrapper until the bean is actually used. Until it is either injected into a non-lazily loaded bean (in that case @LazySingleton would behave exactly like @Singleton), or into another lazily loaded bean that was just created or until it is being looked up using the BeanManager API.

           

          Of course, you're more than welcome to take a stab at it / create a JIRA if you're interested!

           

          Cheers,

          Christian

          1 of 1 people found this helpful
          • 2. Re: lazy singleton support
            marius.gerwinn

            Hallo Christian,

             

            thanks for your answer and the hints regarding an implementation.

            We already have already started implementing lazy singletons in our app using the @LazySingleton Annotation.

            The next weeks we will finish and test this implementation in our app. But its looking good so far. When we think its finished we can make a pull request.

            We will do so eventually when we face to much merge conflicts with the main errai branch

             

            Marius

            • 3. Re: lazy singleton support
              jimmy.pannier

              What about such singleton with lazy loading in errai v3.1.2 ?

              • 4. Re: lazy singleton support
                ben.dol

                Anyone know if this was progressed?

                • 5. Re: lazy singleton support
                  mbarkley

                  In Errai 4, @Singleton and @ApplicationScoped beans are no longer instantiated before they are injected somewhere. Furthermore, @ApplicationScoped beans behave as in Weld: they are proxied by the container and are not actually instantiated until a method is invoked.