Page 1 of 1

Order Buttons constantly being Queried

Posted: Sun Apr 19, 2020 12:03 pm
by tmeisinger
I've create a few buttons on the pf:OrderTab and they are specific by Order Type...

If I leverage the QueryStatusEventHandler of the RegisterHandler, it seems to be called many, many times. I'm not able to UnregisterHandler because I need it to interrogate each Order as it is opened.

Is this as designed? Or, I suppose I'm missing something major.

Re: Order Buttons constantly being Queried

Posted: Sun Apr 19, 2020 3:07 pm
by BobRichards
I can only assume the control event handlers are doing what they are supposed to do. In an event driven application, many user interactions can generate flurries of events that are seamlessly handled in the background due the lightweight objects being passed (and usually being ignored by objects that do not match the CommandID).

I'm not sure of your intent, but if you want to enable/disable custom controls based on the Settlement type, perhaps you can use the IWindowManager and subscribe to the ActiveDocumentChanged event.

Code: Select all

IWindowManager wndMgr = GetService<IWindowManager>();
wndMgr.ActiveDocumentChanged += WndMgr_ActiveDocumentChanged;
In the handler, the ActiveDocument property returns an IWindowFrame object. Query the frame GetProperty() method to get the Order. If it is null, it is not an order (it might be the Home screen). If you get non-null, you have an order. Look at the settlement type and enable/disable the buttons you need.

Code: Select all

private void WndMgr_ActiveDocumentChanged(object sender, EventArgs e)
{
    IWindowFrame frame = GetService<IWindowManager>().ActiveDocument;
    IOrder order = (IOrder)frame.GetProperty("Order");
    if (order != null)
    {
        // We have an order...
    }
}
As a reminder to others, make sure you check to make sure the order isn't readonly before you write to it in your custom code (order.IsReadOnly).

Re: Order Buttons constantly being Queried

Posted: Mon Apr 27, 2020 11:33 am
by tmeisinger
We tried to go into production using the QueryStatusEventHandler, but that has caused too much of a slow down.

I was able to utilize the Windows Manager to find when an order has changed, but I am not able to reference the Button's Enabled property. Any chance you could give me a head start?

Re: Order Buttons constantly being Queried

Posted: Mon Apr 27, 2020 1:30 pm
by BobRichards
Where do my assumptions break down?
  • Previously you wrote a shell package with buttons with invoke handlers and you could enable/disable.
  • Now you have added to that package the capability to detect when the user changes windows.
  • If the user selects an Order, you can get the order.
  • You can determine if the order is writable and its settlement type.
  • If all of this is in your package, you should be able to call the enable for the button you created from the prior step.
I have not actually written this code as an example so I don't have any specific help. Is this the jist of whay you have done?

Re: Order Buttons constantly being Queried

Posted: Mon Apr 27, 2020 2:00 pm
by tmeisinger
Thanks Bob, I went ahead and registered the invoke handlers upon order change, and then unregister after it is checked. This seems to be much more efficient than what I had before. I was just curious how to reference the Custom Button's Enable property without registering the invoke handlers.

PS: Don't ever think it's you, it's probably always me...

Re: Order Buttons constantly being Queried

Posted: Mon Apr 27, 2020 4:17 pm
by BobRichards
Not to stir the pot but we keep the invoke/query handlers active. I'm curious about why your handlers were slowing the system down. We are in and out of the handlers very quickly. You can't reach out to the database or get non-cached data from the mid-tier or it will really slow the system down.

As long as your system works, I'd stay with it. :)

Re: Order Buttons constantly being Queried

Posted: Wed Mar 31, 2021 10:41 am
by dlerickson
Not sure if this will help, but we had a similar issue:

We had one plugin that used the query status handlers to poll the ISecurityManager for updates to user permissions. This created latency issues that didn't become apparent until we all left the office and started working from home this past year, where the constant requests to the mid-tier were suddenly being done from much slower and intermittent home internet connections. This slowed debugging down to the point of being useless.

The solution was to instantiate and make the queries to the ISecurityManager once at startup, cache the permissions, and register a handler (which rebuilt the cache) with the ISecurityManager's GroupChanged event so that all of the query status handlers were polling the local cached data, and permission changes could be handled on a realtime, as-needed basis.

I don't know if this will help with your specific scenario, but the pattern might be of use.

Re: Order Buttons constantly being Queried

Posted: Wed Mar 31, 2021 3:10 pm
by BobRichards
Thanks for the report. I have never needed to get the ISecurity information in a tight loop. Getting this data requires a round trip to the Select Server so there is significant penalty if it is checked too often. That's why we cache some of this information on the local clients.

Do you know how often the ISecurity information was requested? It sounds like Select was calling the handler Query method very often. Select uses a Pull strategy to update the button state. Apparently the query methods are supposed to be very light-weight (and typically are) so it's OK to call it often. Another possibility was to put a holdoff timer in the query handler so it would only fire once per hour or so. Or just put the call in a
Thread timer loop.

Again, thanks for the report!

Re: Order Buttons constantly being Queried

Posted: Wed Mar 31, 2021 4:21 pm
by dlerickson
@Bob Well, the query handlers were firing very often, on the order of multiple times per second. This plugin was a project that I inherited when another developer left. It didn't take long to see what the problem was, because all the service location and server polling was happening every time, and there were multiple query handlers all calling the method responsible for this, too.

Caching at startup solved the problem. I don't mind the query handlers polling the local cache that often since it's so quick and lightweight. Plus, with the local GroupChanged handler (which rebuilds the cache) wired up to the ISecurityManager, it can apply administrative permission changes to the UI bits almost instantly.