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

start: Make start-browser synchronous. #2740

Merged
merged 2 commits into from
Jan 24, 2023
Merged

start: Make start-browser synchronous. #2740

merged 2 commits into from
Jan 24, 2023

Conversation

Ambrevar
Copy link
Member

@Ambrevar Ambrevar commented Jan 11, 2023

Description

There is no point in having it asynchronous, since anything run in parallel before browser is ready is likely to trigger a race conditions or undefined behaviour.

It simplifies testing a lot.

Fixes #2718 (comment).

Discussion

  • Edit tests to not use nyxt:after-startup-hook since it's not needed anymore.
  • Better name for the promise? @aartaka ?
  • I tried to see if we could generalize the concept, for instance come up with a macro that would automatically synchronize asynchronous functions. It's difficult, because we don't really have a convention for these async functions and it heavily depends on WebKitGTK. For instance, buffer-load is "finished" when the on-signal-load-finished signal is triggered, in which we call the buffer-loaded-hook. This is completely different from start-browser. Can we devise a convention somehow?

Checklist:

Everything in this checklist is required for each PR. Please do not approve a PR that does not have all of these items.

  • I have pulled from master before submitting this PR
  • There are no merge conflicts.
  • I've added the new dependencies as:
    • ASDF dependencies,
    • Git submodules,
      cd /path/to/nyxt/checkout
      git submodule add https://gitlab.common-lisp.net/nyxt/py-configparser _build/py-configparser
    • and Guix dependencies.
  • My code follows the style guidelines for Common Lisp code. See:
  • I have performed a self-review of my own code.
  • My code has been reviewed by at least one peer. (The peer review to approve a PR counts. The reviewer must download and test the code.)
  • Documentation:
    • All my code has docstrings and :documentations written in the aforementioned style. (It's OK to skip the docstring for really trivial parts.)
    • I have updated the existing documentation to match my changes.
    • I have commented my code in hard-to-understand areas.
    • I have updated the changelog.lisp with my changes if it's anything user-facing (new features, important bug fix, compatibility breakage).
    • I have added a migration.lisp entry for all compatibility-breaking changes.
    • (If this changes something about the features showcased on Nyxt website) I have these changes described in the new/existing article at Nyxt website or will notify one of maintainters to do so.
  • Compilation and tests:
    • My changes generate no new warnings.
    • I have added tests that prove my fix is effective or that my feature works. (If possible.)
    • New and existing unit tests pass locally with my changes.

@aartaka
Copy link
Contributor

aartaka commented Jan 11, 2023

I like how it looks! But I want to see the changes to tests too, so that we see how it works in headless scenarios.

  • Better name for the promise? @aartaka ?

No, seems fine. Along the lines of after-startup-hook etc.

  • I tried to see if we could generalize the concept, for instance come up with a macro that would automatically synchronize asynchronous functions. It's difficult, because we don't really have a convention for these async functions and it heavily depends on WebKitGTK. For instance, buffer-load is "finished" when the on-signal-load-finished signal is triggered, in which we call the buffer-loaded-hook. This is completely different from start-browser. Can we devise a convention somehow?

Hmmmmm. The case of buffer-load is even more complex, though: is it finished when on-signal-load-finished fires, or when all the resources are loaded? The latter is not hookable, although it's only then that the page is fully interactive and the loading is done, as far as user point of view is concerned...

So there seems to be no solid convention due to lack of clear meaning for things. That's the same problem I've encountered when trying to abstract our concurrency patterns: we don't have many patterns at all. There are lots of unique cases which are not abstractable because of their.

The only reliable option I can think of for this (a)synchronization is to store the promise/completion predicate inside the function itself. Completion predicate would mean less lpara:fulfill across the code and more autonomy, but more evaluation issues. In any case, storing things inside a function is complicated: MOP, our own function class, define-function macro as a sibling to define-class smartness. That's kinda scary, but curious in the possibilities it opens :D

@aadcg
Copy link
Member

aadcg commented Jan 16, 2023

If nyxt:start is synchronous shouldn't the following work?

CL-USER> (progn (nyxt:start :failsafe t) (nyxt:quit))
Nyxt version 3-pre-release-2-812-g007b59d1b
<INFO> [11:10:28] Source location: #P"/home/aadcg/common-lisp/nyxt/"
<INFO> [11:10:28] Profile: "nofile"
<INFO> [11:10:28] GTK extensions directory: #P"/home/aadcg/common-lisp/nyxt/libraries/web-extensions/"
<INFO> [11:10:29] GTK extensions directory: #P"/home/aadcg/common-lisp/nyxt/libraries/web-extensions/"
<INFO> [11:10:29] Loading #P"/home/aadcg/.local/share/nyxt/history/default.lisp".
NIL
<WARN> [11:10:30] Warning: decide policy error: There is no applicable method for the generic function
                       #<STANDARD-GENERIC-FUNCTION NYXT/RENDERER/GTK::ON-SIGNAL-DECIDE-POLICY (1)>
                     when called with arguments
                       (#<WEB-BUFFER 1269 {100AF24363}>
                        #<CL-WEBKIT2:WEBKIT-NAVIGATION-POLICY-DECISION {100CB77AD3}>
                        :WEBKIT-POLICY-DECISION-TYPE-NAVIGATION-ACTION).
See also:
  The ANSI Standard, Section 7.6.6
<WARN> [11:10:30] Warning: decide policy error: There is no primary method for the generic function
                       #<STANDARD-GENERIC-FUNCTION NYXT:BUFFERS (4)>
                     when called with arguments
                       (NIL).
See also:
  The ANSI Standard, Section 7.6.6.2

@aadcg
Copy link
Member

aadcg commented Jan 16, 2023

Also, I see little sense in having a separate PR for this. Can I move this commit and the thread to #2718? @aartaka

@aartaka
Copy link
Contributor

aartaka commented Jan 16, 2023

Hmmmm. I'd rather separate those two, because synchronous start is quite a set of concepts and problems. Would be beneficial to resolve this PR on its own to not bring more issues into the same context.

@aadcg
Copy link
Member

aadcg commented Jan 16, 2023

Ok, then I'll wait for developments on this PR.

@Ambrevar
Copy link
Member Author

If nyxt:start is synchronous shouldn't the following work?

Yes it should. Will investigate.

@Ambrevar
Copy link
Member Author

There are lots of unique cases which are not abstractable because of their.

@aartaka Looks like you forgot a word :)

@Ambrevar
Copy link
Member Author

(progn (nyxt:start :failsafe t) (nyxt:quit)) fails because threads are terminated out of order, and *browser* is set to NIL.

The fundamental reason behind this is given by SB-THREAD:TERMINATE-THREAD:

The unwind caused by TERMINATE-THREAD is asynchronous [...]

We could use the unportable sb-sys:without-interrupts. Not so great...

Turns out that quiting is really hard... Any better idea?

In any case, this is a general issue and goes beyond this pull request, so I don't think it's a blocker to merge this.

There is no point in having it asynchronous, since anything run in parallel
before browser is ready is likely to trigger a race conditions or undefined
behaviour.

It simplifies testing a lot.
@Ambrevar
Copy link
Member Author

@aartaka Tests don't use after-startup-hook anymore.

@aadcg
Copy link
Member

aadcg commented Jan 23, 2023

Thanks @Ambrevar. Ok to merge?

@aartaka
Copy link
Contributor

aartaka commented Jan 24, 2023

Neat! This PR looks just perfect to me now 🤩

@Ambrevar Ambrevar merged commit 9fa14dc into master Jan 24, 2023
@Ambrevar Ambrevar deleted the synchronous-start branch January 24, 2023 08:40
@Ambrevar
Copy link
Member Author

Done!

@aartaka
Copy link
Contributor

aartaka commented Jan 24, 2023

Thanks, Pierre (´∀`)♡

@aartaka aartaka mentioned this pull request Jan 24, 2023
20 tasks
@aadcg aadcg mentioned this pull request Jan 24, 2023
19 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants