Cycle in procedure! (Or Progress Ping-Pong)

fdumlao

New Member
Ok, so I have a cycle in procedure error, I have refactored the code and attempted different logic, but to no avail.

I attempted to disable the write triggers of the offending table, but that of course does not work (As I learned from experience and from the KB).

I decided then to manually override the trigger by creating a global shared variable that I check for in the beginning of the write trigger. If the variable is greater than 0, I skip the entire contents of the trigger using an if/then statement.

But the trigger is not being called as part of the procedure stack so it dosent pick up the global variable!!

How do I get my global variable value to be picked up in the write trigger??
 

Serj HAMMER

Junior Racer
Where was error fired?

You have a cycle, that try to write to the database and errors during this cycle, does not You? Or it is error inside DB-Trigger?
 

fdumlao

New Member
Basicly the setup started like this (when I took it over):

TableA Write Rule:
Code:
Do Some stuff...
 
RUN otherProcedure.p
 
Do Some more stuff..

otherProcedure.p
Code:
DISABLE TRIGGERS ON LOAD OF TableB
ASSIGN TableB.Field = "Some Value".

TableB Write Trigger
Code:
ASSIGN TableA.Field = "Some Other Value".

This however generates the dreaded "Cycle in procedure" error (a stack trace shows it is happening in "otherProcedure.p") which means obviously that the write triggers for TableB have not been disabled as we have attempted to do. (And according to the knowlege base they cant be disabled in this way anyhow.)

So my solution was this:

TableA Write Rule:
Code:
Do some stuff...
 
RUN otherProcedure.p
 
Do some more stuff...

otherProcedure.p
Code:
{gv-defines.i}
gv-cycle-fighter-flg = yes.
ASSIGN TableB.Field = "Some Value".
gv-cycle-fighter-flg = no.

gv-defines.i
Code:
DEF NEW GLOBAL SHARED VAR gv-cycle-fighter-flg 
          AS LOGICAL INITIAL no.

TableB Write Trigger
Code:
{gv-defines.i}
IF gv-cycle-fighter-flg = NO THEN DO: /* this is ALWAYS NO! Why? */
     ASSIGN TableA.Field = "Some Other Value".
END.

So my solution has not worked, and I suspect that the problem is that the Write Trigger for TableB is not called as part of the Procedure Stack. How else can I get a value from "otherProcedure.p" into the Write Trigger of TableB?
 
Your example seems to indicate you are running otherprocedure from within a trigger. ie, you are trying to disable a trigger from within a trigger, which sounds like you are asking for trouble.

You may need to rethink your logic, then try running otherprocedure persistently.

KB P24918
Title: "What is the scope of the 4GL DISABLE TRIGGERS statement?"

http://tinyurl.com/g7fnr
 
I've just reread you post, and realise my answer doesn't help much - but I still think this is a logic rethink - triggers should be used sparingly I think, and kept as simple as possible. Clearly recursive firing is your problem, so maybe you should disable all related triggers before trying to do what you require.

Alternatively remove/disable one of the triggers before you run your main program, to destroy the dependency.
 
One final thought - if the triggers you are talking about are schema triggers, consider overriding them with session triggers - but I don't think this will simplify matters at all.
 
Top