Wednesday, January 27, 2016

Pub/Sub options in AX

(And now for something completely different)

Someone recently pointed out to me that AX (as of version 6) has the possibility of using publishers.

For those of you who are not familiar with the concept, let me offer a brief, fully biased, explanation.

Pub/sub is a concept where a class A reports (publishes) an event rather than acts on it. Its subscribers, any number of classes, receive the event and perform whatever action it is they think they should do.

A publisher is therefore essentially an event splitter (Careful if you quote me like that. Some people might just bite your head off).

For old-school developers (Yes, I started out as a COBOL clown back in the 80s) this is totally dreadful. Structured programming is completely out the window, as execution becomes somewhat unpredictable.

Let me show an example:

The publisher class:

class Elsevier
{
    public static void eventHandler1(XppPrePostArgs _args)
    {
    }
    public void callme()
    {
        this.delegate1();
    }
    delegate void delegate1()
    {
    }
}

And three subscribers:

class ReadElsevier1
{
    static void method1()
    {
        info("Oh when the Saints");
    }
}

class ReadElsevier2
{
    static void method1()
    {
        info("Go marching in");
    }
}

class ReadElsevier3
{
    static void method1()
    {
        info("That's when I like to be in that number.");
    }
}

And then stitch it all together like this:

static void Job10(Args _args)
{
    Elsevier     elsevier = new Elsevier();

    elsevier.delegate1 += eventhandler(ReadElsevier1::method1);
    elsevier.delegate1 += eventhandler(ReadElsevier2::method1);
    elsevier.callme();
    elsevier.callme();
    elsevier.delegate1 -= eventhandler(ReadElsevier1::method1);
    elsevier.delegate1 -= eventhandler(ReadElsevier2::method1);
    elsevier.delegate1 += eventhandler(ReadElsevier3::method1);
    elsevier.callme();
    elsevier.delegate1 += eventhandler(ReadElsevier1::method1);
    elsevier.delegate1 += eventhandler(ReadElsevier2::method1);
    elsevier.delegate1 -= eventhandler(ReadElsevier3::method1);
    elsevier.callme();
}

Nutshell: Publisher Elsevier has a delegate method (event broker) that publishes every time the method callme is called. With the eventhandler we subscribe (and unsubscribe) the classes ReadElsevierX to the publications.

When I execute the job, I get:

image

Not quite what I was aiming for, and when I execute it again:

image

Oh the horror! Chaos has descended upon us. The order of events is determined by heartbeats and clock ticks, not through structure and programming lore.

What I like to think is that the execution of events is determined by processor availability rather than through processing wait time. From that perspective this method is the slicing of the bread in an era where single core systems are as extinct as COBOL programmers.

Of course you need some serious processes to rake in the benefits of this multi-threading technique, but it’s good to know that it’s available if you ever should need it. And in case you always wondered what these oddball delegate methods are doing, you now have the answer: PubSub has come to your neighborhood.

There is much more to say about the subject. PubSub is intended for asynchronous messaging between applications and will without doubt be available as such in the future. Imagine that an AX class can publish an event to any of your other software. The possibilities are unlimited.

Ff649664.despublishsubscribe_f01(en-us,PandP.10).gif

For now AX Won’t even allow publishers and subscribers to be on a different tier. If a publication is done server side, then the subcription class must also be RunOn server. So don’t run off with this concept quite yet.

More reading:

Wikipedia

How to use X++ Delegates in Dynamics AX 2012

Interesting article about pubsub in C#

No comments:

Post a Comment