publish/subscribe internals

Posted by bronco on 31-Oct-2012 02:36

Normally when a publish has no subscibers there’s little to no overhead doing the publish. My question in however when you do a publish like:
this-object:AfterRowSave:Publish(this-object, new AfterRowSaveArgs(blah1, blah2)).
is the AVM clever enough so that no AfterRowSaveArgs object is instantiated when there are no subscribers? My assumption is that the AfterRowSaveArgs object is instantiated no matter what and therefor this solution is less than optimal when it comes to speed.

Thanks.

All Replies

Posted by Admin on 31-Oct-2012 02:54

is the AVM clever enough so that no AfterRowSaveArgs object is instantiated when there are no subscribers? My assumption is that the AfterRowSaveArgs object is instantiated no matter what and therefor this solution is less than optimal when it comes to speed.

I doubt that the AVM is that "clever" - and I'm not quite sure if it should. That would reverse the execution of the statement in comaprison to every other function execution.

First, if would be easy for you to test that - with a MESSAGE in your AfterRowSaveArgs class constructor.

When Progress would not execute the NEW they'd make the assumption that the object you pass in to the PUBLISH does nothing else then serve as an parameter class. They do these assumptions nowhere else. So it would be inconstistent if they'd do it here.

Maybe it would be better if they'd implement a method to query the number of event subscriber? That way, you'd be in control.

Posted by jmls on 31-Oct-2012 02:56

it looks like it is clever enough

using Progress.Lang.*.

routine-level on error undo, throw.

class foo:

constructor foo():

     message "here" view-as alert-box.

end.

end class.

now, with the following code

/* SUBSCRIBE TO "foo" ANYWHERE. */

PUBLISH "foo" (NEW foo()).

PROCEDURE foo:

    DEF INPUT PARAMETER a AS foo.

    MESSAGE "done".

END.

with the commented out code, no message "here" appears.

uncomment the subscribe, and the message does appear.

YMMV

updated: speeling was never my strong point ...

Posted by Admin on 31-Oct-2012 03:07

Just tested it using OO-ABL.

Same result as Julian. I'm surprised!

Not yet 100% if I like that.

Posted by jmls on 31-Oct-2012 03:12

#1 oh, I need to publish -> check for subscribers -> none ->phooey. don't bother doing anything else

#2 oh, I need to publish -> check for subscribers -> yup -> get parameters -> send them

it may work left to right, like the if statement

if true or false then

will never evaluate false condition as it short-cicuited on true

Posted by rbf on 31-Oct-2012 03:14

Maybe it creates an object for each subscriber?

Posted by Admin on 31-Oct-2012 03:18

Maybe it creates an object for each subscriber?

Surely not - as the subscribes can communicate with each other by the properties of the event args objects (i.e. e:Cancel)

Posted by Admin on 31-Oct-2012 03:23

Maybe it creates an object for each subscriber?

Need to correct my earlier reply.

I does! And that's probably equally worse than NEW'ing them when not needed.

In the cases where we use the e:Cancel or similar to allow subscribers to communicate with each other and the published, the e was created before the publish, so that the subscriber keeps a reference.

NEW'ing it twice sounds like a bug to me.

Posted by jmls on 31-Oct-2012 03:24

i'm afraid that it does create a new object for each subscriber

Posted by jmls on 31-Oct-2012 03:25

if you create the object before the publish

x = new foo()

publish(x)

then the class is only created once, and passed to each subscriber

Posted by jmls on 31-Oct-2012 03:27

I still find it amazing that even old dinosaurs like us** can still be surprised by things that were around since v6 (?)

** yes, Mike, I include you in this definition. You may be young, but you are an ABL dinosaur

Posted by Admin on 31-Oct-2012 03:28

i'm afraid that it does create a new object for each subscriber

Noticed that as well. Do you agree that does not feel right?

Posted by rbf on 31-Oct-2012 03:35

jmls wrote:

I still find it amazing that even old dinosaurs like us** can still be surprised by things that were around since v6 (?)

** yes, Mike, I include you in this definition. You may be young, but you are an ABL dinosaur

I consider myself an ABL dinosaur as well but I expected this behavior... what does that make me?

BTW pub/sub was introduced in v9 if I am not mistaken.

But I may be mixed up having started with 3.2E in 1985

Posted by jmls on 31-Oct-2012 03:40

it makes you part of the gang

it looks like your memory is a lot better than mine (surprise surprise!) http://www.futureproofsoftware.com/cms/index.php?page=to-publish-or-to-run

Posted by Admin on 31-Oct-2012 03:43

>> ** yes, Mike, I include you in this definition. You may be young, but you are an ABL dinosaur

 

I started in V5

BTW pub/sub was introduced in v9 if I am not mistaken.

 

But OO Pub/Sub was introduced in V10.2B and a lot has changed since V9.

OO Pub/Sub looks like a method call - a single method call. So it should also behave like one.

Posted by jmls on 31-Oct-2012 03:43

ah, yes, v3. Good old v3.

Best we could do was to align the frames side by side because you couldn't overlay

All we had was 64k to hold our r-code in

Of course, we had it tough. It took us 5 hours to compile 200 programs, whilst all trying to fit in on a 10MB hardcard

Try telling the young people of today that and they won't believe you ...

Posted by jmls on 31-Oct-2012 03:44

lol - I was still playing with the v9 style pub/sub, not the oo pub sub

Posted by jmls on 31-Oct-2012 03:50

it feels right for the v9 style pub/sub

it certainly doesn't feel right for the oo style pub/sub

Posted by Admin on 31-Oct-2012 03:53

it certainly doesn't feel right for the oo style pub/sub

Thank you Julian! I owe you a beer. That saved my day a bit.

Posted by bronco on 31-Oct-2012 03:54

Gee, you produced quite some output while I was driving to the office

I think I got the answer that I wanted and even more! Thanks for your insights.

Posted by rbf on 31-Oct-2012 03:55

jmls wrote:

it feels right for the v9 style pub/sub

it certainly doesn't feel right for the oo style pub/sub

Why? It is both pub/sub.

Posted by Admin on 31-Oct-2012 03:57

lol - I was still playing with the v9 style pub/sub, not the oo pub sub

Why on this planet, should I play with procedural code?  ;-)

Posted by jmls on 31-Oct-2012 04:02

because, even though it pains me to have toi admitt this, I thought that the original question was using v9 pub/sub.

Ok, so it wasn't.

Now my eyes are failing as much as my memory

Posted by jmls on 31-Oct-2012 04:04

I'm not a c# expert, but I know that you are - how does this compare to pub/sub in c# ? Does a new object get created for each subscriber ?

Posted by Admin on 31-Oct-2012 04:13

I'm not a c# expert, but I know that you are - how does this compare to pub/sub in c# ? Does a new object get created for each subscriber ?

Good question

First, typically in .NET (and I suggest in the ABL as well) there's always an On method that raises the even. So when it comes to the actual event publish, where are passing in an object reference, now a NEW expression.

Second, I believe / hope that it's not creating multiple instances. But I'll try out tonight.

Posted by Peter Judge on 31-Oct-2012 08:23

jmls wrote:

Now my eyes are failing as much as my memory

This is good news for us who might or might now owe you a beer.

In a more serious note, if the behaviour  for strongly-typed events (to give them their formal name) is that one event args is created per subscriber when the NEW statement is used in the Publish() statement, then I would log a bug. As Mike said, there's a precendent in (at least) C# for having a single instance passed to all subscribers; and the use-case he describes makes perfect sense. We (PSC/OE) should at the very least clarify the expected behaviour (although I agree that it smells like a bug).

this-object:AfterRowSave:Publish(this-object, new AfterRowSaveArgs(blah1, blah2)).

-- peter

Posted by Admin on 31-Oct-2012 14:03

We (PSC/OE) should at the very least clarify the expected behaviour (although I agree that it smells like a bug).

 

Peter, are you taking care of that or do we need to kick start that?

Posted by Peter Judge on 31-Oct-2012 14:08

I can log a bug if it's confirmed to be such, but in this case, since investigation is required, it would be better for one of you guys on this thread to log a call with tech support.

-- peter

Posted by Admin on 31-Oct-2012 14:11

C# NEW's the EventArg exactly one. Regardless of the number of subscribers (0, 1, ...n).

But you CAN test, if there's at least one subscriber:

            if (SampleEvent != null)

            {

                SampleEvent(this, new MyEventArgs());

            }

You must love this language...

namespace WindowsFormsApplication1

{

    class MyEventArgs : EventArgs

    {

        public MyEventArgs()

        {

            MessageBox.Show("Constructor");

        }

    }

    public partial class Form1 : Form

    {

        public event EventHandler SampleEvent;

        public Form1()

        {

            InitializeComponent();

            this.SampleEvent += new EventHandler(Form1_SampleEvent);

            this.SampleEvent += new EventHandler(Form1_SampleEvent2);

            SampleEvent(this, new MyEventArgs());

        }

        void Form1_SampleEvent(object sender, EventArgs e)

        {

            MessageBox.Show("Event Handler");

        }

        void Form1_SampleEvent2(object sender, EventArgs e)

        {

            MessageBox.Show("Event Handler2");

        }

    }

}

Posted by jmls on 31-Oct-2012 16:34

pjudge wrote:

This is good news for us who might or might now owe you a beer.

ooooohhhh, that is going to cost you _so_ many beers

My memory seems very strangely tuned to remembering who owes me beers. In that regard, I'm like an elephant ...

In a more serious note, if the behaviour  for strongly-typed events (to give them their formal name) is that one event args is created per subscriber when the NEW statement is used in the Publish() statement, then I would log a bug. As Mike said, there's a precendent in (at least) C# for having a single instance passed to all subscribers; and the use-case he describes makes perfect sense. We (PSC/OE) should at the very least clarify the expected behaviour (although I agree that it smells like a bug).

agreed.

Posted by jmls on 31-Oct-2012 16:35

over to you, Mike - send in the sample c# code to prove our point !

Posted by rbf on 01-Nov-2012 03:35

So now it is my time to admit I was wrong

I still find it amazing that even old dinosaurs like me can still be surprised by things that were around since v9

Posted by Peter Judge on 01-Nov-2012 14:14

In a more serious note, if the behaviour  for strongly-typed events (to give them their formal name) is that one event args is created per subscriber when the NEW statement is used in the Publish() statement, then I would log a bug. As Mike said, there's a precendent in (at least) C# for having a single instance passed to all subscribers; and the use-case he describes makes perfect sense. We (PSC/OE) should at the very least clarify the expected behaviour (although I agree that it smells like a bug).

agreed.

After some internal discussion we decided this was indeed a bug, and logged OE00226991 for it if you want to associate yourself with it.

-- peter

Posted by Admin on 01-Nov-2012 14:18

After some internal discussion we decided this was indeed a bug, and logged OE00226991 for it if you want to associate yourself with it.

 

Thanks!

This thread is closed