Coding 2021-12-08
So, after forgetting that I should have been planning to use an interface called MetaBuilder, which barely means anything, I decided that I need to re-evaluate the class and interface names in this project. I'm going to start more or less at the base, because there are issues all over the place.
First up, a few that I barely care about:
- In test_helpers.py, there's an App subclass called MOTRTest. I honestly forget whether I named it, or the template named it, but it doesn't matter.
- In core/exc.py, there are some Exception subclasses. Probably the biggest problem is that I haven't defined enough of these.
- In controllers/base.py, there's a Controller subclass. It's... whatever.
- In motr_app.py, there's the MOTR subclass of App, which makes complete sense.
Anyway, the core runtime logic lives in core/runner.py. This code processes the classes from core/registry.py, but I'm going to cover runner.py first.
In addition to its classes, runner.py also defines a type alias.
- RuntimeAction defines the basic unit of customization for MOTR. If you define a class that implements this interface, you can use it in your configuration.
- TaskWrapper is basically an internal implementation detail. It takes a nullary awaitable with None return value, and awaits its value exactly once, blocking subsequent calls until the first call returns. It doesn't really matter what this is called, because it's never used outside of this module.
- Target, in this module, coordinates access to various common resources.
- Action, in this module, wraps Target and a specific RuntimeAction to provide the last bits of logic required to correctly dispatch work.
Between these three public names, there's a bunch wrong. The most obvious issue is that Target is a callable that takes as its argument an instance of a different type called Target. These types are all named after the corresponding-ish concept from make, and I'm not sure how much that really illuminates things. I suspect that calling the MOTR version of the concept something like "outcome" might make it clearer.
Like "One of this [action]'s outcomes is the creation of a junit.xml file". One thing that would support this idea would be to remove the use of a bare path in the definition of the other Target/Outcome type, and replace it with a Created wrapper. (Presumably, it would need a bunch of wrapper methods to support some of the things I do with Input[Path] instances currently.)
I also kind of want to rename the concept of Action to Task, because you can do either of them, but unlike an "action", you can "set" a "task" for someone else.
That's sort of beside the point in the context of this module, because these classes mostly shouldn't be using these names the way they are. For a first approximation, here's what I want:
- RuntimeAction -> Task
- Target -> Coordinator or Solver or Provider or something. Taskmaster? I'm not really sure. Runner?
- Action can be, like, TaskRunner, maybe?
I think part of the confusion her on my part stems from the... somewhat weird signatures some of these callable classes have. Like, the class-currently-known-as Action has to have a signature of "nullary async" to work with the TaskWrapper.
I think I need to think about this some more. For now, I want to wrap up early.
Good night.