The variable $in_error_state is set back to FALSE from any call to watchdog() not just the first one handling the call. I think this is wrong.

Comments

dave reid’s picture

Are you getting an error for this? I don't see why this needs to be changed.

kbahey’s picture

Component: base system » watchdog.module
Status: Needs review » Postponed (maintainer needs more info)

I am not sure what this patch is trying to solve.

Can you explain what error do you get or wrong behavior that led you to do it this way?

AlexisWilke’s picture

Code correctness.

The following is what you have now. Simplified. If you cannot see the BIG error, then I cannot help. That sample will run. I'm not too sure when it will stop however. The string "I'm running the loop!", according to the comment in the real function, will be written once. Will it?

function run_only_once() {
   static $avoid_recursivity = FALSE;

   if(!$avoid_recursivity) {
    $avoid_recursivity = TRUE;

    echo "I'm running the loop!";
    for($i = 1; $i < 10; ++$i) {
      run_only_once();
    }
  }
  $avoid_recursivity = FALSE;
}

Code correctness in the entire system is what makes the system work better. And the idea of not fixing something because no one has a problem with it, even though it is wrong, does not make sense, does it?

Thank you
Alexis Wilke

dave reid’s picture

But this is not necessarily a recursive function. What happens in the watchdog invokes hook_watchdog in other modules. If those modules cause an error, it will cause another call to watchdog for the new error. In that case, the $avoid_recursivity is TRUE, so the second watchdog call does not execute and stops recursion.

kbahey’s picture

I see what you are seeing from a theoretical point of view, when programming threads and such.

If a second request comes in to watchdog while the first one is active, then regardless of your patch, we have the same result, we do not execute anything between the braces.

There is no loop in watchdog, and the end result is the same : turn the semaphore off after the critical code executes.

So, at best it is a code style issue, but not a practical issue that needs to be solved.

dave reid’s picture

A more accurate simulation is this:

function mywatchdog() {
  static $avoid_recursivity = FALSE;

  if(!$avoid_recursivity) {
    $avoid_recursivity = TRUE;
    mywatchdog_watchdog1();
    mywatchdog_watchdog2();
  }
  $avoid_recursivity = FALSE;
}

function mywatchdog_watchdog1() {
  echo "watchdog1\n";
}

function mywatchdog_watchdog2() {
  // Cause an error, run watchdog
  mywatchdog();
  echo "watchdog2\n";
}

// Cause an error, run watchdog
mywatchdog();

which if run, will result in:

watchdog1
watchdog2

and no recursion, exactly as the original code intended.

AlexisWilke’s picture

Dave,

I'm sorry you cannot see it.

I'll try again...

Your example does prevent the loop only on the 1st error, not the following ones. Why can't you see it?!

function mywatchdog() {
  static $avoid_recursivity = FALSE;

  if(!$avoid_recursivity) {
    $avoid_recursivity = TRUE;

    echo "EXECUTING WATCHDOG";

    mywatchdog_watchdog1();
    mywatchdog_watchdog2();
  }
  $avoid_recursivity = FALSE;
}

function mywatchdog_watchdog1() {
  // Cause an error, run watchdog
  mywatchdog();
  echo "watchdog1\n";
}

function mywatchdog_watchdog2() {
  // Cause an error, run watchdog
  mywatchdog();
  echo "watchdog2\n";
}

// Cause an error, run watchdog
mywatchdog();

And this time the result is something a bit more complex...

EXECUTING WATCHDOG
watchdog1
EXECUTING WATCHDOG
watchdog1
... [continuing until PHP crash]

Let me know if you find a different result.

And of course, feel free to move the line were we put the variable back to FALSE inside the if() to see the difference. Now this may already have caused mayhem to a few people...

kbahey, I do not know what programming theory you are talking about, but you may want to test the code properly: TWICE instead of ONCE. And my sample has no threading issue. Actually, that code, even fixed, would NOT work in a multi-threaded environment. For that you'd need a lock. But that's fine, PHP is not multi-threaded anyway.

dave reid’s picture

Version: 7.x-dev » 6.x-dev
StatusFileSize
new586 bytes

Aha! I see what you mean now! Sorry if this got a little heated, but just wanted to understand the problem completely.

This is a valid bug in Drupal 7 CVS. There is no recursion variable checks in D6 or 5. Maybe there should be (should be separate issue)? Anyway, bumping version to 7.x-dev and attaching patch for review.

dave reid’s picture

Version: 6.x-dev » 7.x-dev
Status: Postponed (maintainer needs more info) » Needs review

Forgot version bump.

AlexisWilke’s picture

Ha! Yes... not even in D6... 8-)

I'm glad you understand in the end.

Thank you.
Alexis

kbahey’s picture

Version: 6.x-dev » 7.x-dev
Priority: Minor » Normal
Status: Needs review » Needs work

Alexis

Now it is clear. If the code sample was complete from the start, we would have seen it earlier.

Thank you for your persistence and patience.

The patch does apply, but I have not tested it.

Setting this to normal priority.

dave reid’s picture

Status: Needs work » Needs review

Bumping back to code needs review.

Status: Needs review » Needs work

The last submitted patch failed testing.

AlexisWilke’s picture

Status: Reviewed & tested by the community » Needs work

Hi Khalid,

I noticed that this was still open and now the computer tells me that the patch is not passing some tests.

Am I supposed to do something about it?!

Thank you.
Alexis

damien tournoud’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new841 bytes

@AlexisWilke: it was your responsibility, as a patch submitter, to clearly explain what issue you intended to solve with your original patch. "I think this is wrong" is clearly not a good enough explanation. Patch reviewers are not (always) clairvoyant, so the more details you give, the better.

Latest patch still apply, but our test bot is having some issues at the moment. I rerolled the patch in #8, with additional comments. The original code was introduced in (you will not believe it), the huge, kitten-killer, monstrous and un-reviewable DB: the new generation patch. I believe that the non-recursion logic of this should be back-ported to D6, once D7 has been fixed.

AlexisWilke’s picture

Status: Needs work » Reviewed & tested by the community

Hey!

That's it 8-) A 344Kb patch... 8-) (that DB the new generation node)

You see, the author accepted and it is one line that was at the wrong place, he even ran a test to see the problem and it does not get fixed and back ported immediately. It would take under 1h altogether and one less bug in the whole system. Then you avoid the 344Kb patches that fixes all these bugs at once... Okay, j/k, I just won't have the time to read 302 messages. But I can see that the problem is quite different. I just think that the process is very slow for such simple patches to be applied.

Thank you for posting a new patch and letting me know that the system has a problem because all my patches are generated failures now... This was not the only one!

Best,
Alexis

dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks for the careful analysis and review, folks! Thanks Alexis.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.