[asterisk-dev] Gosub and Macro

Tilghman Lesher tilghman at mail.jeffandtilghman.com
Tue May 27 09:59:07 CDT 2008

On Tuesday 27 May 2008 08:13:36 Atis Lezdins wrote:
> On Tue, May 27, 2008 at 7:36 AM, Tilghman Lesher wrote:
> > On Monday 26 May 2008 22:12:59 Russell Bryant wrote:
> >> On May 26, 2008, at 12:25 PM, Atis Lezdins wrote:
> >> > * create app_macro_wrapper which provides the same apps as app_macro
> >> > but uses GoSub internally. This could be selected in menuselect by
> >> > default to force new users use GoSub instead, but anybody could
> >> > disable it and use old app_macro as before.
> >>
> >> I would like to see this, as well.  However, Tilghman has indicated
> >> that writing a Macro implementation that uses GoSub internally would
> >> be extremely difficult, and perhaps impossible.  Perhaps he can
> >> comment some more on this.
> >
> > There are several ways in which Gosub and Macro differ in behavior, and
> > these differences are extremely difficult to emulate.  The first is what
> > happens when a hangup occurs.  In Macro, a hangup triggers an immediate
> > implicit return (or MacroExit) from every concurrently executing Macro.
> > Gosub, on the other hand, isn't really even executing at that point, so
> > there isn't a code path that exists whereby the Gosub can empty the
> > return stack and return to the original place.
> >
> > One of the most fundamental differences between Macro and Gosub, which is
> > the primary reason why Macro cannot be implemented with Gosub is the
> > behavior of a completely different application, Goto.  If you call a Goto
> > with a context other than the currently executing Macro, then the Macro
> > exits implicitly and execution continues at the location the Goto
> > specified.  However, as there is no Gosub code executing at the time a
> > Goto is executed (all Gosub really does is to create a "gosub stack
> > frame" which may be later referenced by Return), it is unable to destroy
> > the stack frame.
> >
> > At a very fundamental level, Macro and Gosub are completely at odds about
> > how to do things.  Macro, as it continues executing until the macro ends,
> > specifies all sorts of behaviors that Gosub simply can't do as a
> > standalone lightweight subroutine generator.  Now the fact that it's
> > lightweight means that where Macro would fall over at a certain execution
> > depth, Gosub can keep going deeper.  While I can't imagine anybody going
> > deeper than even 50 levels deep, Gosub can reach 100,000 levels deep and
> > keep digging.  Macro isn't very good at going several levels deep.  It is
> > by design limited to 7 levels deep, although I've seen people tweak it to
> > go 22 levels deep, and I've even seen a crash caused by Macro going only
> > 5 levels deep.
> >
> > There are several other important differences, but those are enough to
> > give you an idea of just how difficult it would be to implement Macro
> > with Gosub.
> >
> >> > * ael parser could still generate macro-mymacro contexts without
> >> > Return, so that macros can be called. However i see that then there
> >> > would be troubles with accidentally having them mixed.
> >> > * add option for AEL parser to not replace Macro with GoSub - for
> >> > transitional period
> >> > * issue big warning in UPGRADE.txt mentioning realtime. However this
> >> > could create similar complains as it was recently with commas and
> >> > pipes.
> >>
> >> Does this issue really have anything to do with realtime?  I think the
> >> problem here is that any dialplan that works based on assumptions of
> >> how the AEL compiler works with respect to macros will be broken.
> >> This issue would exist for people calling a macro from extensions.conf
> >> that was implemented in extensions.ael.
> >>
> >> I can't imagine that this is very common, and furthermore, I would
> >> like to strongly discourage making any assumptions about how AEL
> >> compiles into traditional Asterisk extensions.
> >
> > Agreed.  Trying to mix those three methods of programming the dialplan
> > is just asking for trouble.  It would be different if you were using AEL
> > to compile your dialplan to a database for realtime execution, but that's
> > clearly not the case.
> Well, it would be good if I could write AEL code into realtime, but
> unfortunately it's not possible, as realtime dialplan is generally
> changing data that's generated by custom frontend.

I meant using your custom frontend and compiling the AEL directly into
code for the realtime database, just as the pbx_ael parser does now.

> Replacing Macro 
> calls to GoSub would mean that I have to change frontend. In my case I
> actually can do that easily, but I raised this because of
> compatibility. Probably there are lot of users out there who will have
> exactly the same problem.

You mean the subtle differences between  Macro and Gosub functionality?

> What I would want here is a clean upgrade path from 1.4 to 1.6 without
> changing anything else. I want first to upgrade Asterisk and then
> slowly clean up from deprecated things. Of course I could change all

Macro has not gone away in the upgrade from 1.4 to 1.6.  We've simply
introduced a much more stable infrastructure for doing dialplan subroutines.
There are certainly differences in the functionality, but I suspect a lot more
people were frustrated by the limitations in Macro than will be frustrated by
the transition to Gosub.

> the macros to GoSubs and try that out for 1.4 but AEL parser for 1.4
> won't support that automatically. So I could use parser from 1.6 and
> risk running into other compatibility problems.

I thought we've already established that you're using realtime, and not AEL.
Mixing them is clearly not a good idea and was likely to break no matter
what.  AEL is getting more complex in each subsequent major revision --
expecting that you should be able to apply the same hooks from the transition
from AEL 2 to AEL 3 is clearly not realistic.  It's similar to expecting that
undocumented hooks in a C library will persist -- they're likely undocumented
for a reason.
> I clearly understand differences between Macro and GoSub (and after
> this explanation even more of those details), but what I was proposing
> - is to write simple wrapper for app_macro to use GoSub just the same
> way as AEL parser does that. That is - to maintain compatibility just
> between generated code.

Perhaps that would work for your front end generator, but Macro is not a
code generator -- just a code interpreter.  Trying to change dialplan on the
fly also would be very hairy -- self modifying code, anyone?


More information about the asterisk-dev mailing list