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

feature request: execute template tabs sequentially, rather than in parallel #1061

Open
colemickens opened this issue Feb 14, 2022 · 9 comments
Labels
enhancement New feature or request help wanted Extra attention is needed
Milestone

Comments

@colemickens
Copy link

I have a multi-step workflow that I want to monitor with zellij. If I could tell zellij to execute my tabs in order, rather than in parallel, I can do some interesting things, like effectively run my CI pipeline as a zellij workflow, where can I watch the steps, see the fanout as multiple panels, and so on.

Particularly, I'd like to combine this with "keep-open" or "hold" functionality so that I could go back and review the finished output from earlier steps.

I could probably coordinate this myself with sentinel files or a named pipe or something like that, but it'd be nice to have it in zellij, possibly. Alternatively, I'd understand if this were considered out of scope.

@jaeheonji
Copy link
Member

Is there a specific example? For example, when creating a tab through a layout, does it mean that the creating of each tab is sequentially synchronized(ensure the creation of the previous tab)?

@colemickens
Copy link
Author

Yes. An example, I use Nix to build NixOS systems for all of my machines. I have a workflow that is:

  1. Update all nix inputs, commit.
  2. Update all our custom package inputs, with commits for each package.
  3. Run zellij with a layout that shows 4 panes in a grid: x86 builder, x86 htop, aarch64 builder, aarch64 top

What I'd like is:

  1. Tab opens - runs ./update-all-nix-inputs-script
  2. This script completes successfully, and the pane is held open by virtue of (some resolution to) Allow panes to remain open after their process exited #707
  3. Since the script finished successfully, the next tab is spawned, and then ./update-custom-package-inputs.sh runs
  4. Again, it finishes successfully
  5. Spawn a new tab with the grid layout (which I already am doing)

Right now, I just run the two update steps, then spawn the layout, but the layout replaces the existing terminal view, so the history of the first two steps is sort of lost.

If I took this even further, it would almost be like GitHub's CI view, where they internally emit identifiers that allow them to chunk log output and show log-output per-step even within the context of a single bash script -- while I think that's overkill, it would still be nice to leverage zellij's facilities to manage buffers of smaller script executions. I could even imagine a "sidebar" plugin that is able to show these tasks as a sort of tree and allow the user to switch between those buffers for introspection.

@colemickens
Copy link
Author

To answer your question further, it could even just spawn all of the tabs at once and have a message "waiting for execution for tab XYZ to continue" or some-such, if there's concern about tabs surriously appearing in an existing session mixed with other tabs. Or a common name prefix too?

@jaeheonji
Copy link
Member

jaeheonji commented Feb 15, 2022

Thank you for the detailed example!. It was really easy to understand 👍
After reading your explanation, I thought this would be quite useful.

For example, it would be good if there were the following options.

$ zellij --layout-path example.yaml --execute sequential # or parallel

But this is my simple concept idea.

I think this function will take quite a lot of effort. So, it's necessary to listen to other people's opinions.

@jaeheonji jaeheonji added enhancement New feature or request help wanted Extra attention is needed labels Feb 15, 2022
@colemickens
Copy link
Author

I think the UX I was imagining was a new yaml config bit under each tab that has:

---
tabs:
  - id: step_1
    name: step 1
    ...
  - id: step_2
    name: step 2
    depends_on_success: step_1

or something like this.

@imsnif
Copy link
Member

imsnif commented Feb 15, 2022

Hey - I really like this idea!

I'd be very happy to see this functionality in Zellij. UX-wise I don't see an issue with it. Implementation-wise, this will be a little challenging. Namely: a lot of our internal logic assumes constructing a layout is something that happens on startup.

That being said, I'd be very happy to mentor anyone through this issue if they're up for a wild ride.

@a-kenji
Copy link
Contributor

a-kenji commented Feb 15, 2022

The tabs currently are executed sequentially, but they fork so they don't block each other. The way it works: All the processes are started sequentially and then the panes and tabs are constructed and the processes filled in.

Your idea to add dependencies to the tabs is fantastic I think.

You can already do some small steps of your workflow, but they are not as ergonomic as we would like them to ideally be.

Tab opens - runs ./update-all-nix-inputs-script
This script completes successfully, and the pane is held open by virtue of (some resolution to)
#707

You can keep the pane open with your script, if you don't return from the script:

nix flake update
read -p "Press any key to exit."

You can also run commands that return and keep a pane open, but that is shell dependent:

          - pane_name: update inputs
            run:
              command: {cmd: fish, args: ["-C nix flake update"]}

Also, you can bind opening panes and tabs in the configuration (currently not in the layouts yet - that change was sadly reverted due to an issue - but that should be fixed in #1036)

So for example that would be a viable configuration:

        - action: [
          NewTab: {
          direction: Vertical,
          run: {command: {cmd: "htop"}},
        }
        ]
          key: [ Char: '3',]

Sadly the yaml makes nesting here rather tedious, but you can bind your

Run zellij with a layout that shows 4 panes in a grid: x86 builder, x86 htop, aarch64 builder, aarch64 top

to a single keybind. Or any of those steps really.

I think the actual implementation of the dependency will be rather involved, but there is one issue that would already make this quite achieveable in a fairly straight forward manner:

#413 , If we can invoke actions from the command line, we can invoke them from actions, or scripts. That way a tab could be spawned on the success of a previous tab/command/linter/etc ... .

@fsevenm
Copy link

fsevenm commented May 24, 2023

The tabs currently are executed sequentially, but they fork so they don't block each other. The way it works: All the processes are started sequentially and then the panes and tabs are constructed and the processes filled in.
ncies to the tabs is fantastic I think.

I am curious, although they are started sequentially, are the process in each pane are running in parallel?

@imsnif
Copy link
Member

imsnif commented Jun 29, 2023

For what it's worth, now that we overhauled our plugin system this is very much possible through plugins. I even wrote a plugin that does this (could definitely be improved upon though): https://github.com/imsnif/multitask

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants