Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GAIAPLAT-1205] Do not fire a rule if the anchor row is invalid #882

Merged
merged 9 commits into from
Sep 2, 2021

Conversation

daxhaw
Copy link
Contributor

@daxhaw daxhaw commented Aug 27, 2021

It is possible to delete the row after a rule has been scheduled but before it has been invoked. This results in an invalid row being sent to the rule. We have made the decision to not let this happen. The rules engine now checks that the anchor row is valid before invoking the rule. If an anchor row is not valid, the rule will not be invoked.

Also fixed up tests and enabled a setting to turn this "db checking" off. This is done so that unit tests can test the event manager and rule invocations without the database itself.

Also included a random change to get rid of an unused variable warning in the translation engine. <!sorry>

Copy link
Contributor

@simone-gaia simone-gaia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM: just a nit about comments.

{
}

rule_checker_t(bool enable_catalog_checks, bool enable_db_checks)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you comment on what these checks are actually doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the following to the class header:

/**
 * This helper class is used by the rules engine at both rule
 * subscription and invocation time.  Currently, the class performs 
 * the following checks.
 * 
 * Catalog Checks:
 *  Ensure tables and fields that are referenced in a rule are
 *  actually present in the catalog at rule subscription time.
 * 
 * Database Checks:
 *  Ensure that an anchor row is valid before invoking a rule.
 * 
 * Note that the checks can be disabled by unit tests that do not want
 * to have a dependency on the database.  These tests can intialize
 * the rules engine with custom settings.  See event_manager_settings.hpp 
 * and rules_test_helpers.hpp for more information.
 */

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

Comment on lines +15 to +30
* This helper class is used by the rules engine at both rule
* subscription and invocation time. Currently, the class performs
* the following checks.
*
* Catalog Checks:
* Ensure tables and fields that are referenced in a rule are
* actually present in the catalog at rule subscription time.
*
* Database Checks:
* Ensure that an anchor row is valid before invoking a rule.
*
* Note that the checks can be disabled by unit tests that do not want
* to have a dependency on the database. These tests can intialize
* the rules engine with custom settings. See event_manager_settings.hpp
* and rules_test_helpers.hpp for more information.
*/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to determine what user-facing documentation that needs to be provided.
Does affect a rule as it processes and forward chaining?

Copy link
Contributor Author

@daxhaw daxhaw Aug 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two important messages:

  1. Gaia guarantees that a rule is passed a valid anchor row.
  2. Gaia determines the validity of an anchor row before calling a rule. If the anchor row is invalid, the rule will not be called.

One way for an anchor row to be invalidated is the following sequence events:

  1. a row is inserted, a transaction is committed and a rule bound to the insert event is enqueued
  2. that same row is deleted, and a transaction is committed before the rule enqueued in step 1 is invoked
  3. the rules engine goes to invoke the insert rule enqueued in step 1 but now it won't because that row got deleted. Note that whether the row got deleted in the same transaction as when it was inserted or a different transaction doesn't matter.

@daxhaw daxhaw requested a review from waynelwarren August 30, 2021 16:35
Copy link
Contributor

@simone-gaia simone-gaia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question, should you remove the gaiat logic that adds the IF at the beginning of the rule?

@waynelwarren
Copy link
Contributor

@simone-gaia , I agree that the rule code should assume the presence of the anchor. The extra 'if' in the generated code is unnecessary.

@daxhaw
Copy link
Contributor Author

daxhaw commented Sep 1, 2021

@simone-gaia, @waynelwarren : I'll look into removing the extra checks now in gaiat.

@daxhaw daxhaw merged commit c9c95d1 into master Sep 2, 2021
@daxhaw daxhaw deleted the dax/validate_anchors branch September 2, 2021 17:14
@senderista
Copy link
Contributor

So what happens when the rules engine checker loses a race with a txn deleting the anchor row, so the check succeeds but the anchor row has been deleted in the rule invocation's snapshot?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants