Jump to content

How many times is a Module's init() function called for autoload modules?


alxndre
 Share

Recommended Posts

I just happened upon something that I think is curious, and I'm wondering if this is default behavior. So help me because I know nothing. :)

While writing a module, i logged something in wire('log') inside the module's init() function. I was surprised to see that the text was being logged multiple times continuously. So I tried to open a small random module and logged something in its init() function as well, and the same thing happened - the text being logged many times.

My question is, is this supposed to happen? I just want to understand what's going on. My concern is that if I do something huge in the init function, it will get called repeatedly, as with the log, and cause performance issue. Please note that these are both autoload modules. I was expecting them to log at least once when I refresh, but not continuously like what happened.

Please let me know. Thanks.

Link to comment
Share on other sites

Having 'singular' => false (default) in your getModuleInfo() method allows multiple instances of the module. If you're instantiating the module in one of your template files and it gets executed more than once, init() method will be called for each instance. You can set singular to false to limit the module to single instance, but the issue might be caused by something else.

 

  • Like 1
Link to comment
Share on other sites

Log something in your class constructor and check /site/assets/logs/<class>.txt, if you're seeing multiple entries, then the class is being instantiated more than once. Otherwise something else is calling init() method

public function __construct()
{
    $this->log('test');
}

 

  • Like 1
Link to comment
Share on other sites

Every request will create an entry, even ajax request in the background. So if you look at the log, it will poll it all couple seconds creating a new entry. Otherwise it's called once for every request, unless you have multiple instances.

You shouldn't do something in the init other than setting properties, hooks or something. No resource heavy stuff if not needed.

  • Like 2
Link to comment
Share on other sites

@alxndre You may install the following testmodule and then go to admin > setup > logs > AutoLoadTest and watch the log growing :)

Spoiler

<?php namespace ProcessWire;

class AutoLoadTest extends WireData implements Module {

    public static function getModuleInfo() {
        return array(
            'title'     => __('AutoLoadTest', __FILE__),
            'summary'   => __('AutoLoadTest', __FILE__),
            'version'   => '0.0.1',
            'singular'  =>  false,
            'autoload'  =>  true,
            'requires'  => 'ProcessWire>=3.0.18, PHP>=5.4.0'
        );
    }

    static protected $counter = 0;

    public function __construct() {
        $this->log(__METHOD__ . ', counter: ' . (self::$counter++) . ', timestamp: '. time());
    }

    public function init() {
        $this->log(__METHOD__ . ', counter: ' . (self::$counter++) . ', timestamp: '. time());
    }

    public function ready() {
        $this->log(__METHOD__ . ', counter: ' . (self::$counter++) . ', timestamp: '. time());
    }

}

 

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

2 hours ago, alxndre said:

I'm an idiot. So it's because I'm watching the log page trying to poll the logs. :D

Thanks guys.

It should be noted though that if you have the core notifications module installed you'll probably see the same thing, which is why I have this line in Tracy to prevent it being loaded by notifcations polling.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...