[asterisk-dev] Gosub and Macro

Atis Lezdins atis at iq-labs.net
Wed May 28 04:34:27 CDT 2008

On Tue, May 27, 2008 at 5:59 PM, Tilghman Lesher
<tilghman at mail.jeffandtilghman.com> wrote:
> 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.

Ok, after discussion with Tilghman in IRC, i still have hope that this
will be working at some degree.

I wrote a wrapper that calls GoSub with all arguments passed to Macro
command, so basically it will work
just like AEL parser, and allow to use "macro" declarations from
realtime without changing anything. This of course won't allow full
features of Macro, however that was broken at point when AEL parser
started translating macro commands to GoSub. So, this is just
extending that change (which i find great btw).

I would ask anybody interested to take a look at this
http://bugs.digium.com/view.php?id=12735 and comment. As this is my
first complete module, i could have done some things wrong, so please
mention that, and i'll try to make it better.


Atis Lezdins,
VoIP Project Manager / Developer,
atis at iq-labs.net
Skype: atis.lezdins
Cell Phone: +371 28806004
Cell Phone: +1 800 7300689
Work phone: +1 800 7502835

More information about the asterisk-dev mailing list