Leo's run levels

71 views
Skip to first unread message

Terry Brown

unread,
Jul 5, 2017, 4:51:05 PM7/5/17
to leo-editor
I'm wondering if it would be a useful thought experiment to list a
series of "run levels" (https://en.wikipedia.org/wiki/Runlevel) or
levels of initialization for Leo - just a textual list where we do our
best to be aware of dependencies for each level.

So for example, in UI initialization, you might have:

- main window exists
- outline managing added (top row of tabs)
- pane management system added
- log added
- tree added
- minibuffer added
- find added
- spell added
- a body added

the idea being that nothing further up the list depends on anything
further down the list.

I think in the case of settings, the goal with the sqlite approach is

- g exists
- g.config added
[now within load init. for workbook.leo]
- config created (to become c.config, even though c not created yet)

so config objects are created and ready to use without the need to
read outlines.

This is somewhat orthogonal to using sqlite as a format for outlines,
although using sqlite as a format for outlines gets around the problem
of two separate files for an outline and its local settings.

I'm just as interested in the UI case as the settings case, getting a
better handle on that would help a lot with the "view rendered 4" and
Qt dock projects.

So I guess a first cut would be working out the order of creations and
deferments in the UI startup code.

Cheers -Terry

Edward K. Ream

unread,
Jul 6, 2017, 3:57:26 AM7/6/17
to leo-editor
On Wed, Jul 5, 2017 at 3:51 PM, Terry Brown <terry...@gmail.com> wrote:
I'm wondering if it would be a useful thought experiment to list a
series of "run levels" (https://en.wikipedia.org/wiki/Runlevel) or
levels of initialization for Leo - just a textual list where we do our
best to be aware of dependencies for each level.

​This hasn't provoked any interesting thoughts.​
 
​ Yet.  Let me know if it does for you ;-)

Edward

vitalije

unread,
Jul 6, 2017, 4:43:16 AM7/6/17
to leo-editor

So I guess a first cut would be working out the order of creations and
deferments in the UI startup code.

Cheers -Terry
If I may add to this idea, it would also be very useful to have a list of ivars that somehow represent current state of Leo application, ivars that get changed through user interaction. When reloading Leo application we don't want to change any of this ivars. For example in this list belongs currently selected position, scroll positions, ratios of panes, position and size of window, undo/redo history, history of visited nodes, search patterns history, ...

In clojurescript world there is a figwheel tool which reloads client code in browser as soon as is changed on disk. Clojurescript programmers are advised to use different macros for defining such ivars. For all things that need to change after reload one should use `def` command, and for all things that should preserve their value after reload one should use `defonce` instead of `def`. That way during development code stays reloadable most of the time.

There are no `defonce` in Python, but it can be simulated and it can be matter of convention.

Vitalije

Edward K. Ream

unread,
Jul 9, 2017, 3:15:06 AM7/9/17
to leo-editor

It does seem that a more orderly, official and documented startup process would be beneficial in many ways.

I am sympathetic to the general idea.

Edward

Edward K. Ream

unread,
Jul 16, 2017, 10:58:06 AM7/16/17
to leo-editor
On Sunday, July 9, 2017 at 2:15:06 AM UTC-5, Edward K. Ream wrote:
On Wed, Jul 5, 2017 at 3:51 PM, Terry Brown <terry...@gmail.com> wrote:
I'm wondering if it would be a useful thought experiment to list a
series of "run levels" (https://en.wikipedia.org/wiki/Runlevel) or
levels of initialization for Leo - just a textual list where we do our
best to be aware of dependencies for each level.
It does seem that a more orderly, official and documented startup process would be beneficial in many ways.

I keep coming back to this idea. Keeping details deliberately vague, the startup process might be something like:

1. Init the most basic vars, and do the most basic imports.
2. For each loaded file, init all of Leo's settings, using sqlite and maybe a new "minimal" Commands class to read settings files when necessary.
3. Everything else.  That is, create a commander for each to-be-loaded file, init the commander thoroughly, and create the outline from sqlite or the actual external file.

This is pure speculation.  I may be relying on sqlite for too much magic.  Hope not.

As more magic, it would super if we could get rid of caching entirely...

Edward

Terry Brown

unread,
Jul 16, 2017, 12:00:45 PM7/16/17
to leo-e...@googlegroups.com
On Sun, 16 Jul 2017 07:58:06 -0700 (PDT)
"Edward K. Ream" <edre...@gmail.com> wrote:

> On Sunday, July 9, 2017 at 2:15:06 AM UTC-5, Edward K. Ream wrote:
> >
> >> On Wed, Jul 5, 2017 at 3:51 PM, Terry Brown
> >> <terry...@gmail.com> wrote:
> >>
> >>> I'm wondering if it would be a useful thought experiment to list a
> >>> series of "run levels" (https://en.wikipedia.org/wiki/Runlevel) or
> >>> levels of initialization for Leo - just a textual list where we
> >>> do our best to be aware of dependencies for each level.
> >>
> >> It does seem that a more orderly, official and documented startup
> >> process would be beneficial in many ways.
> >
> I keep coming back to this idea. Keeping details deliberately vague,
> the startup process might be something like:

:-) I think there's an intuitive sense that there might be some
potential for simplification, which would be very valuable. When you
think about the components and how they relate, it doesn't seem like
there needs to be so much forward declaration and split
initialization. Although it's entirely reasonable that such situations
arise through code evolution - adding tabs to the log pane is I think a
good example. There was a critical point where it could have
conceptually been "add the log widget to the tab pane" rather than "add
tabs to the log pane", but at that point the implications were much
less obvious than they are now.

So my thought with this non-code based run-level / init. steps listing
is that it will either show opportunities for simplification, or
illustrate clearly why some entangling is unavoidable.

Must admit I'm currently looking at it much more from GUI startup for
the QDocks branch than basic outline loading, but I think the same
process applies in both cases.

> 1. Init the most basic vars, and do the most basic imports.
> 2. For each loaded file, init *all* of Leo's settings, using sqlite
> and maybe a new "minimal" Commands class to read settings files when
> necessary. 3. Everything else. That is, create a commander for each
> to-be-loaded file, init the commander thoroughly, and create the
> outline from sqlite or the actual external file.
>
> This is pure speculation. I may be relying on sqlite for too much
> magic. Hope not.
>
> As more magic, it would super if we could get rid of caching
> entirely...

As hinted in my other post re "yes to all", I can't help feeling that
caching is getting a bad rap, assuming it's working reasonably. I
think it's being blamed for things it shouldn't be causing, unless it
and / or reload have unidentified flaws. And my recollection is that
it causes a massive decrease in load time of outlines with many
external files. I guess that at least is easy to test.

Cheers -Terry

Edward K. Ream

unread,
Jul 16, 2017, 3:00:39 PM7/16/17
to leo-editor
On Sun, Jul 16, 2017 at 11:00 AM, Terry Brown <terry...@gmail.com> wrote:

:-) I think there's an intuitive sense that there might be some
potential for simplification, which would be very valuable. 

​I agree, but startup code is the ruin of all intuition...
 
it doesn't seem like
​ ​
there needs to be so much forward declaration and split
​ ​
initialization.

​Computing all local settings before creating most objects would surely help untangle the Gordian Knot.
 
Although it's entirely reasonable that such situations
arise through code evolution - adding tabs to the log pane is I think a
good example.

​At this point, the choices are lost in pre-history. The finishCreate pattern dates from Apple's Yellow-Box days, which pre-dates Borland C++.

It will be interesting to look at everything with fresh eyes. I welcome any suggestions you may have, tested or not.

Edward

Xavier G. Domingo

unread,
Jul 17, 2017, 12:41:05 AM7/17/17
to leo-e...@googlegroups.com
I'm wondering if it would be a useful thought experiment to list a
series of "run levels" (https://en.wikipedia.org/wiki/Runlevel) or
levels of initialization for Leo - just a textual list where we do our
best to be aware of dependencies for each level.
It will be interesting to look at everything with fresh eyes. I welcome any suggestions you may have, tested or not.

Edward

I think Terry's idea is great. I don't know how do Runlevels exactly work in *nix OSs nor what is your idea on how to implement them in Leo, but it occurs to me that it could even be useful to have a g.initState ivar or similar that explicits the current initialization "phase" in which Leo is at any moment. This could be leveraged to add asserts all around the initialization code to check that Leo is in fact at the expected initState for that code. At the very least, it may help in the "migration" phase to the new startup code.

What do you think?

Xavier

Edward K. Ream

unread,
Jul 17, 2017, 7:35:26 AM7/17/17
to leo-editor
On Sun, Jul 16, 2017 at 11:41 PM, Xavier G. Domingo <xgdo...@gmail.com> wrote:

​>​
 it occurs to me that it could even be useful to have a g.initState ivar
​.

This would be a good idea if it phases can be defined simply. We shall see...

Edward

Terry Brown

unread,
Jul 17, 2017, 8:33:29 AM7/17/17
to leo-e...@googlegroups.com
On Mon, 17 Jul 2017 01:41:00 -0300
"Xavier G. Domingo" <xgdo...@gmail.com> wrote:

> I think Terry's idea is great. I don't know how do Runlevels exactly
> work in *nix OSs nor what is your idea on how to implement them in
> Leo, but it occurs to me that it could even be useful to have a
> *g.initState* ivar or similar that explicits the current
> initialization "phase" in which Leo is at any moment. This could be
> leveraged to add asserts all around the initialization code to check
> that Leo is in fact at the expected initState for that code. At the
> very least, it may help in the "migration" phase to the new startup
> code.
>
> What do you think?
>
> Xavier

Hmm, I meant my idea to be a thought experiment, maybe resulting in a
list of steps, not actual code. OTOH, unix runlevels formalize a kind
of set up / tear down sequencing that might have some value. Not sure,
shutdown of a whole computer's more complicated than Leo shutdown,
which can mostly be handled by the gc and OS without any effort on our
part.

But having a list of named stages might be a useful thing for any
startup redesign that does occur, to help with thinking about at what
stage things should happen.

Cheers -Terry
Reply all
Reply to author
Forward
0 new messages