Developers,
Although I’ve been thinking about these ideas for a long time, I finally have a concrete solution to propose. First, I’ve put these ideas into a first draft of a PR, mostly to be very concrete about the plan:
Some comments:
- No filter, rules, gramplets, etc. need to change. Everything will continue to work as it has. People can still write code like they have.
- Over time, we can slowly move code (especially expensive to run code) from all over the code base to a centralized collection of “business logic” methods. (This is a term we used to use as a way of deciding what should not be in the database code)
- At the same time, we can provide database-specific implementations for speed
- The current low-level code requires adding a new columns to each primary table.
Ok, but the devil is in the details. The idea is to create a new abstraction class called BusinessLogic
. In this class, we move some code out of filters, rules, gramplets and other plugins to here. These might be expensive functions like get_person_handles_that_have_common_ancestor_with_person()
(this is based on a real filter). Here is an example from the PR:
def get_father_mother_handles_from_primary_family_from_person(
self,
handle=None,
person=None
):
""" High-level implementation """
if handle:
person = self.get_person_from_handle(handle)
fam_id = person.get_main_parents_family_handle()
if fam_id:
fam = self.get_family_from_handle(fam_id)
if fam:
f_id = fam.get_father_handle()
m_id = fam.get_mother_handle()
return (f_id, m_id)
return (None, None)
As a mixin, this will be a method of the db. The code is mostly copied directly from the IsAncestorOf
rule. And now we refactor the rule slightly to call the new method.
f_id, m_id = db.get_father_mother_handles_from_primary_family_from_person(person=person)
So far we have only refactored and moved code to a different place. By itself, this is a good thing. We keep implementing the same functions over and over again. Now, they will be in a standard location. (Third-party plugins can use the old system, or any of the new business logic functions.)
So, we start out with our normal, slow, unpickled primary objects, and one by one write low-level replacements for your favorite backend.
Possible variations:
- maybe name all
BusinessLogic
methods (say prefixed with “biz_”) for easier understanding - we can combine the BusinessLogic mixin with DB in a few ways
Downsides:
- The business logic is based on lowlevel details, and might need to be changed if the DB changes. We can do some work to make that better
- It will takes some work to write the low-level code
Upsides:
- A way forward to make gramps much faster than today, without requiring any code changes in the gramplets
- Is a clean way to manage abstract and low-level implementations
- We can incrementally make each gramplet faster
Of course, comments, questions, and critiques welcomed.