[vtk-developers] [VTK 0012044]: Order of called observers

David Cole david.cole at kitware.com
Mon Apr 4 15:43:32 EDT 2011


People who need ordering guarantees are likely using observer priorities to
achieve a guarantee.

So.... they probably don't need ordering guarantees as much as they need
"don't change the behavior on me for no good reason" guarantees.

Changing the documentation alone would at least preserve the existing
behavior. Changing the implementation will change the behavior, and in some
cases, probably in a not-very-nice way. (i.e. event callbacks that used to
be called may no longer be called if the ordering changes...)

You cannot document in "AddObserver" that there is any particular order
without taking the "focus" observers into account. So if you do document an
enforced order, make sure the documentation is thorough.


David C.


On Mon, Apr 4, 2011 at 3:39 PM, Julien Finet <julien.finet at kitware.com>wrote:

> If people didn't need ordering guarantees, then "passive", "focus" and
> observer "priorities" wouldn't be there.
>
> If we define the order to be arbitrary, there is a cost associated to it.
> People would need to enforce their order by adding extra code (increased
> number of code, extra computation time).
>
> Julien.
>
>
> On Mon, Apr 4, 2011 at 3:18 PM, tom fogal <tfogal at sci.utah.edu> wrote:
>
>> I was trying to constify that code recently, and I don't think either of
>> the explanations is accurate.
>>
>> The actual ordering appears to be:
>>
>>  1. invoke all "passive" observers (which cannot change system state)
>>  2. invoke "focus" observers
>>  3. invoke anything not invoked by the above
>>
>> (see InvokeEvent for full info)
>>
>> I'd say it's better to make the order undefined... do people really need
>> ordering guarantees (what's a use case?)?
>>
>> -tom
>>
>>
>> On 04/04/2011 12:18 PM, Julien Finet wrote:
>>
>>> The question here is:
>>>
>>> 1) do we change the documentation and claim the order of callbacks is
>>> undefined (fix documentation) or
>>> 2) do we enforce that the observers are called in the order they were
>>> added
>>> (fix bug).
>>>
>>> What are benefits of the later and former solution ?
>>>
>>> While 1) is definitely safer, I doubt that it can be a safe long-term
>>> solution.
>>> Moreover, I believe that 2) has a somewhat limited impact.
>>>
>>> Please let us know what you think,
>>>
>>> Thanks,
>>> Julien.
>>> p.s. For information, the Qt framework was documenting an arbitrary order
>>> until the last versions 4.5, they are now (since 4.6) following the order
>>> when the connections are added.
>>>
>>>
>>> On Mon, Apr 4, 2011 at 2:15 PM, Mantis Bug Tracker<
>>> mantis at public.kitware.com>  wrote:
>>>
>>>
>>>> The following issue has been SUBMITTED.
>>>> ======================================================================
>>>> http://public.kitware.com/Bug/view.php?id=12044
>>>> ======================================================================
>>>> Reported By:                Julien Finet
>>>> Assigned To:
>>>> ======================================================================
>>>> Project:                    VTK
>>>> Issue ID:                   12044
>>>> Category:                   (No Category)
>>>> Reproducibility:            always
>>>> Severity:                   major
>>>> Priority:                   normal
>>>> Status:                     new
>>>> ======================================================================
>>>> Date Submitted:             2011-04-04 14:15 EDT
>>>> Last Modified:              2011-04-04 14:15 EDT
>>>> ======================================================================
>>>> Summary:                    Order of called observers
>>>> Description:
>>>> Nightly build documentation of vtkObject::AddObserver() says: "When
>>>> events
>>>> are
>>>> invoked, the observers are called in the order they were added."
>>>>
>>>> However the first observer of any given priority (default 0. included)
>>>> is
>>>> always
>>>> called last.
>>>> For observers added in the following order:
>>>> observer1
>>>> observer2
>>>> observer3
>>>> observer4
>>>>
>>>> The actual calling order is:
>>>> observer2
>>>> observer3
>>>> observer4
>>>> observer1<- notice how the first observer is called last
>>>>
>>>>
>>>> Steps to Reproduce:
>>>> void objectModified1(vtkObject *caller,unsigned long eid, void
>>>> *clientData,
>>>> void
>>>> *callData) {
>>>>  std::cout<<  "modified1"<<  std::endl;
>>>> }
>>>>
>>>> void objectModified2(vtkObject *caller,unsigned long eid, void
>>>> *clientData,
>>>> void
>>>> *callData) {
>>>>  std::cout<<  "modified2"<<  std::endl;
>>>> }
>>>>
>>>> void objectModified3(vtkObject *caller,unsigned long eid, void
>>>> *clientData,
>>>> void
>>>> *callData) {
>>>>  std::cout<<  "modified3"<<  std::endl;
>>>> }
>>>>
>>>> void objectModified4(vtkObject *caller,unsigned long eid, void
>>>> *clientData,
>>>> void
>>>> *callData) {
>>>>  std::cout<<  "modified4"<<  std::endl;
>>>> }
>>>>
>>>> int Test(int,char *[])
>>>> {
>>>>  vtkObject* obj = vtkObject::New();
>>>>
>>>>  vtkCallbackCommand* callback1 = vtkCallbackCommand::New();
>>>>  callback1->SetCallback(objectModified1);
>>>>  obj->AddObserver(vtkCommand::ModifiedEvent, callback1);
>>>>
>>>>  vtkCallbackCommand* callback2 = vtkCallbackCommand::New();
>>>>  callback2->SetCallback(objectModified2);
>>>>  obj->AddObserver(vtkCommand::ModifiedEvent, callback2);
>>>>
>>>>  vtkCallbackCommand* callback3 = vtkCallbackCommand::New();
>>>>  callback3->SetCallback(objectModified3);
>>>>  obj->AddObserver(vtkCommand::ModifiedEvent, callback3);
>>>>
>>>>  vtkCallbackCommand* callback4 = vtkCallbackCommand::New();
>>>>  callback4->SetCallback(objectModified4);
>>>>  obj->AddObserver(vtkCommand::ModifiedEvent, callback4);
>>>>
>>>>  obj->Modified();
>>>>
>>>>  callback4->Delete();
>>>>  callback3->Delete();
>>>>  callback2->Delete();
>>>>  callback1->Delete();
>>>>
>>>>  obj->Delete();
>>>>
>>>>  return 1;
>>>> }
>>>>
>>>> Output:
>>>> modified2
>>>> modified3
>>>> modified4
>>>> modified1
>>>>
>>>>
>>>> Additional Information:
>>>> Current code (and suggested fix):
>>>>
>>>>
>>>> //----------------------------------------------------------------------------
>>>> unsigned long vtkSubjectHelper::
>>>> AddObserver(unsigned long event, vtkCommand *cmd, float p)
>>>> {
>>>>  vtkObserver *elem;
>>>>
>>>>  // initialize the new observer element
>>>>  elem = new vtkObserver;
>>>>  elem->Priority = p;
>>>>  elem->Next = NULL;
>>>>  elem->Event = event;
>>>>  elem->Command = cmd;
>>>>  cmd->Register(0);
>>>>  elem->Tag = this->Count;
>>>>  this->Count++;
>>>>
>>>>  // now insert into the list
>>>>  // if no other elements in the list then this is Start
>>>>  if (!this->Start)
>>>>    {
>>>>    this->Start = elem;
>>>>    }
>>>>  else
>>>>    {
>>>>    // insert high priority first
>>>>    vtkObserver* prev = 0;
>>>>    vtkObserver* pos = this->Start;
>>>>    while(pos->Priority>= elem->Priority&&  pos->Next)
>>>>      {
>>>>      prev = pos;
>>>>      pos = pos->Next;
>>>>      }
>>>>    // pos is Start and elem should not be start
>>>>    if(pos->Priority>  elem->Priority)   ////////////////////////// HERE
>>>> IT
>>>> SHOULD BE: pos->Priority>= elem->Priority
>>>>      {
>>>>      pos->Next = elem;
>>>>      }
>>>>    else
>>>>      {
>>>>      if(prev)
>>>>        {
>>>>        prev->Next = elem;
>>>>        }
>>>>      elem->Next = pos;
>>>>      // check to see if the new element is the start
>>>>      if(pos == this->Start)
>>>>        {
>>>>        this->Start = elem;
>>>>        }
>>>>      }
>>>>    }
>>>>  return elem->Tag;
>>>> }
>>>> ======================================================================
>>>>
>>>> Issue History
>>>> Date Modified    Username       Field                    Change
>>>> ======================================================================
>>>> 2011-04-04 14:15 Julien Finet   New Issue
>>>> ======================================================================
>>>>
>>>> _______________________________________________
>>>> Powered by www.kitware.com
>>>>
>>>> Visit other Kitware open-source projects at
>>>> http://www.kitware.com/opensource/opensource.html
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.vtk.org/mailman/listinfo/vtk-developers
>>>>
>>>>
>>>>
>>>
>>>
>>> _______________________________________________
>>> Powered by www.kitware.com
>>>
>>> Visit other Kitware open-source projects at
>>> http://www.kitware.com/opensource/opensource.html
>>>
>>> Follow this link to subscribe/unsubscribe:
>>> http://www.vtk.org/mailman/listinfo/vtk-developers
>>>
>>>
>>
>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtk-developers
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20110404/9112889f/attachment.html>


More information about the vtk-developers mailing list