Jump to content

Risks of using module init()?


Recommended Posts

In order to keep all my module-related code in one place and encouraged by the experience of others (particularly @bernhard), I moved the contents of site/init.php into a module's init() method thinking that the code would be called at a similar time. However, I am now not convinced this is a great idea, but I don't understand enough about PW's inner workings to see what is actually happening.

The problem is that, while everything works fine in my dev environment, various random things break in the live system. I have no idea why, as the code, database, PW version and PHP version are the same. I have already documented here the problem that occurred with page classes. I fixed that by moving the include for the page classes from init() to __construct(). I then had another problem noted here plus a few other minor issues with functions declared in init(). The problems were resolved by moving the code back into init.php. None of these problems occurred in the dev environment. (BTW I had done something similar with 'ready' - I'm not sure that caused the problems but I moved it all back into ready.php just in case).

This has been very frustrating as it has broken my site several times despite testing everything carefully in the dev system first. It also means that I can't gather all the module-related code together. I'm wondering whether there might be something odd with my hosting service (which I am thinking of changing anyway) but without a detailed understanding of the flow of control in PW I don't even know the right questions to ask.

Any thoughts, comments or pointers to where I can look to get a better understanding of the PW processes would be most welcome.

 

 

Link to comment
Share on other sites

At this level of uncertainty, this is where I'd probably set up xdebug to integrate with an IDE to step through processes. Alternatively, maybe Ryan's ProfilerPro in ProDevTools to compare how the module version works vs the traditional?

  • Like 3
Link to comment
Share on other sites

@MarkE in order to get rid of any frustration, I suggest you try to understand the order of execution of pw, as suggested by @BrendonKoz profiling a fresh install, and then adding your module and starting profiling again, and then comparing each runs is your best bet and will make things clearer for you.

If you dont have ProfilerPro, just tell us if you are running on windows or linux and I will write you a small tutorial to get a profiler with xhprof, it's easy and take 2 minutes.

  • Like 4
Link to comment
Share on other sites

Posted (edited)

Is your module configured as autoload? Also, as @flydev beat me to the punch, I assume this is some sort of an execution order problem you are having. My question is exactly about that... any non-autoload module actually gets loaded and initialized only on-demand, e.g. only at a certain point down the road when you are actually using it (in a hook for example) which might be after PW decides which PageClass to use. Also, gathering from your other posts, config.php might be too early in the OOE and ready.php might be too late.

EDIT: I have had these problems in the past. I took on the whole PW core in an afternoon in order to understand how stuff works and especially, how PW works under the hood. This shed a ton of light into how to do things and where to hook into. Right now, if I am having a problem, I am just looking at the actual source code as my documentation.

Edited by poljpocket
clarify and add info
  • Like 3
Link to comment
Share on other sites

Thanks @BrendonKoz, @flydev, @poljpocket. I have actually had the problems with two separate modules, both of which are autoloaded. I have ProDev tools so will try the profiler, but I suspect that stepping through with xdebug may be necessary. I have a feeling it will take a while to diagnose and am under some time pressure to complete this project, so I might need to accept a less-than-ideal solution for now and come back and investigate in more detail when I have time. But thanks for the thoughts and I will post back with any findings.

Link to comment
Share on other sites

BTW, I am having another problem with differences between the dev and live environments. This may be unrelated to the module issues, but here goes anyway:

I have a couple of hooks - ...addHookBefore('Pages::saveReady'... and ...addHookAfter('Pages::saved'... - and am using these to track changes to a specific field. I do this by this code in the before saveReady hook

	$p = $event->arguments(0);
	if ($p->id) {              // Don't carry out this hook for new pages - only for edits
		// Get the previous version of the page
		$oldPage = wire('pages')->getById($p->id, array(
			'cache' => false, // don't let it write to cache
			'getFromCache' => false, // don't let it read from cache
			'getOne' => true, // return a Page instead of a PageArray
		));

In that hook I can save a temporary field (e.g. $p->oldTickets = $oldPage->tickets) and compare that with the new field in the 'after saved' hook. This works fine in the dev system. However, in the live system $oldPage seems be the same as $p in the before hook and $p does not have the updated field in the after hook. I tried getFresh as well as the above code, but that doesn't work either.

Link to comment
Share on other sites

Looking through your other posts again, it seems like your hosting provider does have some problems and actually might be the culprit. We have had some peculiarities with some of them as well. I would suggest you try a completely different provider just to try out your install and make sure it's not the server it's on. So many differences in two systems is very unusual. You can use @flydev's Duplicator module to move it from local to this new environment. 🙂

If you don't have access to something like that, pm me. I have a VPS with a known-good PW environment 🙂

Link to comment
Share on other sites

Also, when you say it isn't working on live environment and everything is identique, does this sentence imply $debug is set to true and tracydebugger is enabled? Just asking as it make the env not the same, and then hooks order is likely not the same.
To make things easier, publish or send via pm a reproducible example 🙂

  • Like 1
Link to comment
Share on other sites

1 hour ago, poljpocket said:

I would suggest you try a completely different provider just to try out your install

I'm planning to change provider anyway (to Krystal) so might just accelerate this!

 

1 hour ago, flydev said:

does this sentence imply $debug is set to true and tracydebugger

Not always, but I have tried this (as superuser and with debug=true restricted to my IP address). I'll investigate some of the latest problems with these on.

 

1 hour ago, flydev said:

To make things easier, publish or send via pm a reproducible example

Not quite sure of the best way of doing this. The code is part of a fully-integrated membership administration and website system that I initially built for one organisation and am generalising for wider use. A demo system will be available when I have changed provider, but the code is proprietary. I could just do a simple site with the code, but it may be that it all works in a much simpler set-up. If I can buid a simple reproducible example then it probably means that I can fix it too!

Link to comment
Share on other sites

Posted (edited)

@flydev is implying that just a difference in $debug configuration or the module TracyDebugger being active or not can make some difference in how PW works in cases as peculiar as yours. That's why you need to make sure your environment is actually identical not just with PHP versions and database versions. We've experienced some problems/differences with Tracy messing up the frontend only when it's enabled (not even necessarily showing it's panels).

Also that's why I suggested you make a carbon copy of your local install and try to run it somewhere else and look for anything that's changed to rule out it being your code or make sure it actually is your code and not something external and out of your control.

Edited by poljpocket
  • Like 2
Link to comment
Share on other sites

@MarkEby reproducible example I mean we could reproduce the issue.

You could for example just publish/paste your module structure without all the business logic. Without code  it’s not easy to help in this case.

Without insisting, profiling your setup will speed also the debug process, as you will see instantly when your module is initialized and maybe also spotting where the glitch happen between the dev and prod.

Maybe we are also going too far and might be a simple permission issue. Idk.

  • Like 1
Link to comment
Share on other sites

Posted (edited)

@MarkE I read the other posts, I do not see any code chunk about how you are calling your hooks. As you said it's working on /site/init.php ..

On 5/20/2024 at 11:54 PM, MarkE said:

I moved the contents of site/init.php into a module's init()

.. you have to remember that calling hooks implies also a context, I mean $wire/wire() vs $this, just a thought. Please confirm / insert coin 🙂

edit: And you might also test hook priority option, check there:

 

Edit 2: I made you a small preview of a diff running debug true vs false, on a almost blank website, there is only one user modue installed:
image.thumb.jpeg.ca594769cb20868afa1ea95d06b66075.jpeg image.thumb.jpeg.02c6a9885b3430a034781db8900f317a.jpeg

Edited by flydev
profiler / diff preview
  • Like 1
Link to comment
Share on other sites

4 hours ago, poljpocket said:

We've experienced some problems/differences with Tracy messing up the frontend only when it's enabled

Sorry to go OT but I would love to know more about this - could you perhaps file a GH issue or post about it in the Tracy forum. Would definitely like to fix any issues you are having.

Link to comment
Share on other sites

On 5/22/2024 at 10:12 AM, flydev said:

Edit 2: I made you a small preview of a diff running debug true vs false, on a almost blank website, there is only one user modue installed:

Thanks @flydev. What are you using to show that - xhprof?

Link to comment
Share on other sites

Yes, in the first screenshot it show the two output files generated by xhprof and the second is a diff tool to compare the two files.

Using a diff tool make easier to see the differences at a glance.

Link to comment
Share on other sites

On 5/22/2024 at 12:01 AM, MarkE said:

I have a couple of hooks - ...addHookBefore('Pages::saveReady'... and ...addHookAfter('Pages::saved'... - and am using these to track changes to a specific field. I do this by this code in the before saveReady hook

	$p = $event->arguments(0);
	if ($p->id) {              // Don't carry out this hook for new pages - only for edits
		// Get the previous version of the page
		$oldPage = wire('pages')->getById($p->id, array(
			'cache' => false, // don't let it write to cache
			'getFromCache' => false, // don't let it read from cache
			'getOne' => true, // return a Page instead of a PageArray
		));

I don't think this is related to the module init() problem. It seems to be to do with the 'oldPage' code above (or getFresh, which is simpler and has the same effect). The problem is, that in my 'before save' hook, the 'getFresh' seems to have the updated field, not the previous one. HSince I am hooking both before and after the page save, I can see that there is no save occurring in between which might update the database version. However, the problem is intermittent with no cause that I can identify. See the log screenshot below, where the sequence of user actions were to change 'tickets' from 3 to 5 and save then from 5 to 6 and save. Reading in time sequence (bottom up), the first update is correct:

  • In the 'before' hook the old tickets field is 3.
  • The next 4 entries are from the 'after' hook. I am getting the changed fields from '$event->arguments(1)' and it shows the tickets field as changed (to 5 tickets).

The next line is from saving a different page

Then in the next 'before' hook we see that the tickets from the 'getFresh' is now 6, although the last save was with 5 tickets, also there are no field changes detected. Any ideas what might be happening?

1305813242_Screenshot2024-05-27132544.thumb.png.aca0c7bc5d06d41a0b1ca8cd6114f52f.png

Link to comment
Share on other sites

Posted (edited)

Still, this is what's happening on your live version, right? And it all works on your local environment?

There must be a difference in the systems which leads to this difference in behavior.

Let me also ask this. Is there a specific reason you don't use a simpler approach like this (careful - untested):

<?php namespace ProcessWire

/**
 * @var Wire $wire
 */

$wire->addHookBefore('Page(template=booking)::changed(tickets)', function($event) {
	$page = $event->object;
	$oldValue = $event->arguments(1);
	$newValue = $event->arguments(2);
	// [...]
}

Or like that (again careful - untested; if you don't care about the old value):

<?php namespace ProcessWire

/**
 * @var Wire $wire
 */

$wire->addHookBefore('Pages::saveReady(template=booking)', function($event) {
	$page = $event->arguments(0);
	
  	if ($page->isChanged('tickets')) {
      	$newValue = $page->tickets;
		// [...]
    }
}
Edited by poljpocket
fix code typo
Link to comment
Share on other sites

1 hour ago, poljpocket said:

Still, this is what's happening on your live version, right? And it all works on your local environment?

Thanks @poljpocket. That seemed to be the case initially. However, with this problem it seems to be occurring intermittently in both environments (mostly it goes wrong, but occasionally it is right).

1 hour ago, poljpocket said:
$wire->addHookBefore('Page(template=booking)::changed(tickets)', function($event) {

I don't think Page has a 'changed' method - hookable or not.

1 hour ago, poljpocket said:
if ($page->changed('tickets')) {

I assume you mean $page->isChanged('tickets'). That suffers from exactly the same problem, which is not a great surprise because using $event->arguments(1) was failing to register the change sometimes too - see the top (last) entry in the screen dump of the log.

Link to comment
Share on other sites

I think I may have identified the problem with the 'getFresh'. It seems that PageAutosave was turned on.  I have refined the module settings to only use it for certain templates. I guess it saves with ‘no hooks’ so it wasn’t showing up. I’ll check it out more thoroughly in the morning. 

UPDATE. I can confirm that the problem was caused by having autosave inadvertantly turned on (+ not realising that it suppressed hooks). This was not helped by the editing taking place in a modal, so it was not obvious. I assume that initially it was turned on in the live environment but not in the dev. The problem was intermittent because, if you hit 'save' quickly enough it does the user-initiated save before the autosave. One to watch!!

  • Like 1
Link to comment
Share on other sites

21 hours ago, MarkE said:

This was not helped by the editing taking place in a modal, so it was not obvious. I assume that initially it was turned on in the live environment but not in the dev.

but but but we told you to try with the same env, anyway glad to hear it's solved, this type of issue kill a kittie each day.

  • Like 2
Link to comment
Share on other sites

On 5/21/2024 at 12:12 PM, poljpocket said:

EDIT: I have had these problems in the past. I took on the whole PW core in an afternoon in order to understand how stuff works and especially, how PW works under the hood. This shed a ton of light into how to do things and where to hook into. Right now, if I am having a problem, I am just looking at the actual source code as my documentation.

Didn't you feel like you were reading a comic book, because it looked so easy and the code is so well written/commented? Ryan is so skilled you quickly realize that the tool is robust lol

Just played with a chatbot that will be soon publicly available (need to ask ryan and mods) with some @MarkE  text chunk from this thread :
image.thumb.jpeg.81ae43488ef4041102de2f0875900473.jpeg

  • Like 4
Link to comment
Share on other sites

On 5/31/2024 at 5:03 PM, flydev said:

Just played with a chatbot that will be soon publicly available (need to ask ryan and mods) ...

I wonder what you exactly mean by that...

Link to comment
Share on other sites

Posted (edited)
On 5/22/2024 at 2:49 PM, adrian said:

Sorry to go OT but I would love to know more about this - could you perhaps file a GH issue or post about it in the Tracy forum. Would definitely like to fix any issues you are having.

Thanks for asking. I have to be honest, it wasn't clear why then and still isn't now. I have looked up the project in question and cannot replicate it anymore with the most recent code base. This project makes heavy use of vue.js for the frontend which lead to several problems with Tracy in the frontend. We ended up just disabling Tracy for the frontend and everything was fine and we stopped looking into it as it did no longer matter. If I'm enabling it now, everything is fine.

Edited by poljpocket
  • 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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...