If you have questions or if you want to share your opinion about Aware IM post your message on this forum
#52232 by ddumas
Mon Dec 02, 2019 8:34 pm
I am a newbie, and am reviewing the tutorial on the Library sample app. It is demonstrated that a business rule is used to set the value of a calculated attribute Item.ItemAvailable (in the Item business Object) as follows:

If COUNT Loan WHERE (Loan in Item.Loans AND Loan.Status='CURRENT') = 0 THEN
Item.ItemAvailable = 'Yes'
ELSE
Item.ItemAvailable = 'No'

I am thinking that Item.ItemAvailable should not be a calculated (derived) attribute from a business rule, but instead be set explicitly, using a Process. The process could use the above logic to explicitly set the (non-calculated) attribute value. From an application performance perspective it would seem to me that reading a persisted database column value would be faster than a runtime derived value. If so, to me it would then follow that you should never use a calculated attribute.

Unless I am just not understanding the concept of using a business rule here?

Is there a best practice of using Business Rules vs Processes?

Thanks,

Dave
#52234 by Jaymer
Mon Dec 02, 2019 9:24 pm
I cannot speak to the issue of best practices, but what you have discovered is akin to this:
if I had a customer master, and I had a balance due field, then I wouldn't want to dynamically calculate that every time I wanted to know what the guys balance was. I would want it maintained in the customer header.
It makes sense that if a book is available, I should just have a field in book master table it says available yes/no.

Many of those sample applications were written long ago come I think 5 plus years.
Without asking the author, it may just have been written as an example of how a business rule can be used.
Since you said the word "process", where in this hypothetical application would you put "the process" to maintain the status of a book availability?

I think if you watch the video on Business Rules, you may get some insight.
Programming with rules is a different animal - and I myself just used something this week for the first time USING a rule where before I would have made it more Procedural (I pushed a button to run a process and in that code, I made something happen). The Rules way would be to do less in the process and let the Object react (via Rules) that something was done to it.

In the library, instead of having multiple hooks throughout the system to maintain the AvailableYN flag, it just determines it on the fly.

Of course, context is important. the size of your system, speed of server, frequency of use of a function.
yes, we tend to want to be efficient - not wasteful of bytes or cpu cycles, but if I'm writing an in-house system for 25-50 users, thats a lot diff. than a SAAS app for the public. If a table is only going to have 1500 records in it, for example, an Inventory table, then who cares if I'm wasting 50-100 extra bytes per record? Having some redundant data de-normalized in there for sake of searching is not that big of a deal.

But if you made one mistake and put a binary field in that rec for a logo/image/etc., you could have a terrible negative impact on system-wide performance every time that inventory rec is read. (read this post)
#52235 by ddumas
Mon Dec 02, 2019 10:17 pm
Jaymer,

I think we might be saying the same thing. Calculating a balance on-the-fly would be bad as you say, so I think the AvailableFlag in the Item table would be best implemented as a regular (non-calculated) column, and populated when a new book loan is created (at save). So, as part of the book loan create, you could use the business rule code to determine if the book is still available (in the database) , and if so, save the loan, and use an AwareIM "Process" to update the Item.AvailableFlag to false. Maybe even use a nullable ReservedOnLoanNumber column instead of the yes/no flag.

However, we are dealing with concurrency here, so if another user is trying to reserve the same book at the same time, how does AwareIM handle that when if fires the business rule / process trigger?

Think of an airline seat reservation. You and I could be viewing that same wonderful exit row on seat selection. If you press the "submit button" before I do, then when I press the submit button, a message should come up for me indicating that seat is reserved.

As you know, in a public facing web app, handling concurrency properly is crucial.

Dave
#52236 by Jaymer
Tue Dec 03, 2019 12:21 am
You can see how aware handles 2 users saving the same record - while being logged into 1 session in your browser, log in again Incognito. Then navigate, edit, & save the save rec.

You'll see a msg when saving the 2nd - "data has been changed by another user".

In a 'real' app, i'm not sure how you get a better msg than that - or prevent a user from seeing that "raw" msg.

Internally, all recs read by Aware have a version/timestamp. So if another user saves the SQL record, the version increments - so Aware can tell that something has tinkered with it.
#52237 by ddumas
Tue Dec 03, 2019 1:12 am
That's great, so sounds like concurrency is handled well. So, in summary, I am thinking its best to use an Aware IM Process (in this case, during the Book Loan process as the look loan is being created) to populate the Item.AvailableFlag, and NOT via a business rule into a calculated attribute.
#52243 by BobK
Tue Dec 03, 2019 4:46 pm
ddumas wrote:I think we might be saying the same thing. Calculating a balance on-the-fly would be bad as you say, so I think the AvailableFlag in the Item table would be best implemented as a regular (non-calculated) column...


Dave,

I may be misreading your posts, but it sounds to me like you misunderstand what it means to set an attribute as "Calculated".

I think of a Calculated attribute as a regular attribute that is protected from everybody except the system. Only the system can update a calculated attribute. It is still stored in the DB and not calculated every time the BO is accessed.

For example using the Library sample application. If you log in as a Library Member and Search the library, the results show the Available field. At that time, the available field was read from the DB and not calculated.


It is true that having the rule:

If COUNT Loan WHERE (Loan in Item.Loans AND Loan.Status='CURRENT') = 0 THEN
Item.ItemAvailable = 'Yes'
ELSE
Item.ItemAvailable = 'No'

on the BO Item, it will be executed every time the Item is updated and recalculated at that time.


You can move the above rule from the BO to a Process and still keep the attribute as Calculated.
#52244 by ddumas
Tue Dec 03, 2019 5:26 pm
Ah ok, so the attribute in an of itself being defined as calculated is fine, and if I understand you, would really be a best practice.

So, in a "Book Loan" "post-save" process, sounds like I could still invoke the code to set the item via that IF-THEN logic. I am still thinking the logic might be best implemented in the Book Loan code as a process and not as a Business Rule in the Item Business Object.

Dave
#52252 by ACDC
Tue Dec 03, 2019 8:48 pm
I am still thinking the logic might be best implemented in the Book Loan code as a process and not as a Business Rule in the Item Business Object.


The rule on the object is the better option

What would happen if the Process was started by two different users at exactly the same time, which one would prevail

An Object rule would render the Form stale and alert the user to refresh form. A process could be executed from anywhere and you wouldn't know

I made something happen). The Rules way would be to do less in the process and let the Object react (via Rules) that something was done to it.

You said it Jaymer, using Business Rules this way is a much more elegant solution.

I have noticed a lot of forum members coming from other dev environments are inclined to want to use Processes most of the time rather than leverage Object rules.

If it weren’t for the option of Object rules some of my applications would have needed highly complicated processes, which I cannot imagine doing. Also I doubt I would have been able to deliver the same reliable highly complex solutions as I have done making Object Rules the goto method
#52257 by ddumas
Wed Dec 04, 2019 11:04 am
ACDC,
I did not get that same interpretation from Jaymers response. I hear you, and I am a newbie to AwareIM. I guess I am thinking in terms of: Is there a single "point of contact" where an availability flag for a book should get updated? If the answer to that is yes - when a loan is requested, then I am thinking that an AwareIM process related to a loan should update that attribute.

Consider the following example:

Let's say there is an attribute on the book, like Condition (excellent, good, worn, etc). If a Staff member needs to update that column, I am thinking that AwareIM does not need to update the Availability attribute by querying the database to look for loans on the book. That, in my opinion, could negatively impact performance. Where you have a business object that gets updates very infrequently you would never notice it. But where you have a business object that gets updates very frequently, you might notice it due to volume, # of users hitting that BO, etc.

Does that make sense?

Dave
#52260 by ACDC
Wed Dec 04, 2019 4:02 pm
Dave,
I am no expert on AwareIm, other than discoveries I have made over the years . I also used to call on Vlad to advise on best practice. Most of the time the Object rule was the way to go– he once used the word “elegant” to describe an Object rule based solution ( I was trying to do it in a Process) and that’s when the penny dropped. From then on, I always try the “elegant” way

Also understanding the science behind the Rete Rules engine put things in perspective for me. Rule based programming is very different

The one thing to remember is the slightest change to any Object, results in ALL the rules on the object firing. There is no way to prevent/control that (except on reference rules). So if you think a Process method is going to be more efficient, no way

As long as the Object rules are optimised and done correctly , overhead impact is minimal as already indicated in the Jaymers response - (Obviously hardware setup and DB is setup is key)

So I would not be concerned about overhead. First plan the Object rule and then go to PROCESS if not possible. In some cases I have a special flags on the object that when set will activate the rule when the object is saved (that’s one way of controlling rules on the object, the others are IF NEW, WAS CHANGED etc )

Looking closer at the “Availability” example, (I haven’t studied the Library example for a long time) but I would have had two separate reference objects on the Book Object managing check ins and check outs. The result being the Availability Status is being updated by the natural workflow

1. Check In Book ( a transaction receipt record is created on initial setup and future checkins)
2. Check Out Book ( a transaction delivery receipt whenever the book is checked out)

Two rules on the Book Object to manage Availability status
1. COUNT the Check IN transactions and Check OUT Transactions
2. Subtract the two totals from each other and then update the availability attribute 1=Available 0=Not Available

This may seem a more complex, but it’s easy to do in AwareIm and I also have a transaction audit trail for reporting and other event rules. BTW book condition would have been an attribute on the Check IN Book transaction updating the Book.Condition via a rule on the CheckInBook object …IF CheckInBook IS NEW…etc ( This could have been part of the Process that Creates The CheckInBook transaction, but I would have placed it on the object rule
#52262 by Jaymer
Wed Dec 04, 2019 6:28 pm
Just to add some things.
While it IS an example, the library application, it may not be a “real world “example.
Marketing is one thing, and creating examples that show ability of the tool helps the product look good.
I don’t know how many years ago the library example was done exactly, and I’m not sure that it was done with SQL in mind, since aware is backend non specific.
I think we’re saying that while the sample app may show some functionality, it doesn’t mean you would do that in your real world application. Just cause it’s done that way in a sample app, doesn’t mean that’s the way you need to do it, which is why I think you’re having questions when you see a particular method.
Also, remember that and support’s answer to one of your other questions, he said well, “it depends”. On many factors.

You’re not going to write the best aware app on your first try. You got to dig in and try some things, and maybe add extra field and references and rewrite some things as you learn more about aware.
#52265 by PointsWell
Wed Dec 04, 2019 9:37 pm
ddumas wrote:ACDC,
I did not get that same interpretation from Jaymers response. I hear you, and I am a newbie to AwareIM. I guess I am thinking in terms of: Is there a single "point of contact" where an availability flag for a book should get updated? If the answer to that is yes - when a loan is requested, then I am thinking that an AwareIM process related to a loan should update that attribute.


Personally I would steer clear of flags when you can derive status from other fields. The reason being is that a flag in and of itself can be accidentally created by poor coding.

In the library example you know that you have two business objects (BO)

Member and Item
Member has a peer multiple relationship to Items and the Item has a reciprocal relationship to Member

Member may borrow many Items
An Item may be borrowed by a Member.

On the Item create a peer single relationship and have it create a matching relationship back to the member which is a many - it is important to do it in this order otherwise you create additional tables on the database which have the potential to be a bottleneck.

When an Item is borrowed then the Item.psBorrowedBy attribute is defined. Your searches then become FIND Item WHERE Item.psBorrowedBy IS DEFINED for all items loaned out.

Use Display Rules if you want to show Borrowed v Available for example in a query or in a form where you don't want the user to necessarily know the Borrower details

The only place where you absolutely must use a flag instead of deriving it is if you are looking for BOs that have date fields that can be NULL. AIM doesn't handle the NULL in dates in searches. In this case you a Business Rule based on the date field to set a Y/N.

Flag fields require processing to set them, preferably in the form of a Business Rule on the BO, which is code to maintain. They also create the risk of accidental setting (or not) for example if you update the BO to say Item.Available=Y but don't set the Item.psBorrowedBy to UNDEFINED then your flag is in conflict with the borrower status.

I was counselled against them by a database guru much wiser than me (he manages the database for one of Europe's largest spread betting company, I do not).
#52276 by ddumas
Thu Dec 05, 2019 9:37 pm
I like Item.psBorrowedBy. Or even Item.LoanNumber. Both of those give more meaning to availability than a flag.

Following that approach, your logic below:

When an Item is borrowed then the Item.psBorrowedBy attribute is defined. Your searches then become FIND Item WHERE Item.psBorrowedBy IS DEFINED for all items loaned out.

It would then seem to me that since psBorrowedBy is striclty in context to a loan being created, a process on the loan object would be best to set Item.psBorrowedBy, correct? If so, then there would by no Business rule on the Item BO related to Item.psBorrowedBy, correct?

Dave
#52278 by PointsWell
Thu Dec 05, 2019 9:48 pm
ddumas wrote:I like Item.psBorrowedBy. Or even Item.LoanNumber. Both of those give more meaning to availability than a flag.

Following that approach, your logic below:

When an Item is borrowed then the Item.psBorrowedBy attribute is defined. Your searches then become FIND Item WHERE Item.psBorrowedBy IS DEFINED for all items loaned out.

It would then seem to me that since psBorrowedBy is striclty in context to a loan being created, a process on the loan object would be best to set Item.psBorrowedBy, correct? If so, then there would by no Business rule on the Item BO related to Item.psBorrowedBy, correct?

Dave


Misunderstood your question so I deleted my answer.

If you go down the route of

Member may have multiple Loans
Loan must have a Member
Loan must have an Item
Item may have a Loan

Then it is a little more complicated as you'd need to track the current Loan but you could do it by a business rule or a process. A business rule on Loan could set the
Code: Select allIF Loan IS NEW AND Loan.DateStart IS DEFINED AND Loan.psItem IS DEFINED AND Loan.psBorrower IS DEFINED
THEN Loan.psItem.psBorrowedBy=Loan.psBorrower

Then when the Item is returned:
Code: Select allIF Loan.DateEnd IS CHANGED AND Loan.DateEnd IS DEFINED THEN Loan.psItem.psBorrowedBy=UNDEFINED

The simplified (though less useful in a business environment) route would be Member to Item.

The intermediary Loan BO would allow for analysis of Loans (eg average loan length, frequency across year) and it is for that reason that I also tend to avoid simplified relationships for fast changing dimension (ie things that aren't just reference data), they are more easily auditable as well. Generally if a BO has a peer multiple relationship to another BO I ask myself is this immutable (e.g. Type of Vehicle, Car, Motorcycle) or is it important that I know when this was added or removed (e.g Paint colour of vehicle)? If it is not immutable then I probably need a Start Date and an End Date and this means I need another BO to be brought into play.

Realistically though a Loan is probably more like an Invoice in that it is a header in as much as a single Loan will probably contain many LoanItems.

While AIM is fast it means it can get you to a sticky situation quickly. I still build a proper Entity Relationship Model to make sure that I fully understand how the data supports my business need. As above, a relatively straightforward question has already generated another 2 BOs that I hadn't considered in my simple "don't use flags" comment.

Who is online

Users browsing this forum: Google [Bot], MSN [Bot] and 25 guests