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

First Cut Of Web UI #182

Closed
azriel91 opened this issue Feb 1, 2024 · 5 comments · Fixed by #197
Closed

First Cut Of Web UI #182

azriel91 opened this issue Feb 1, 2024 · 5 comments · Fixed by #197
Assignees

Comments

@azriel91
Copy link
Owner

azriel91 commented Feb 1, 2024

Related: #125

Use leptos and dot_ix to create a first cut web UI:

  1. Render flow graph
  2. Buttons to invoke commands
  3. Render progress
  4. Render outcome

Interactively rendering additional information, or highlighting the parts of the outcome when the progress step is hovered (or vice versa) is not necessarily in scope.

@azriel91 azriel91 self-assigned this Feb 1, 2024
@github-project-automation github-project-automation bot moved this to Todo in Peace: UI Feb 1, 2024
@azriel91 azriel91 moved this from Todo to In Progress in Peace: UI Feb 5, 2024
@azriel91
Copy link
Owner Author

azriel91 commented Feb 11, 2024

For rendering the flow graph, perhaps the following works:

  1. Create peace_flow_model, and define a FlowSpecInfo which is essentially the Flow without logic.
  2. WebiOutput, is instantiated with FlowSpecInfo, which is passed to a <FlowGraph flow_info=flow_info cmd_progress=cmd_progress /> component.
  3. FlowGraph uses dot_ix to render the graph -- specifying the nodes and edges.
  4. In impl OutputWrite for WebiOutput, the Progress* updates are used to change the WriteSignal<CmdProgress>, which influences the tailwind_css styles passed by FlowGraph to dot_ix.

@azriel91
Copy link
Owner Author

azriel91 commented May 26, 2024

Refactorings to make drawing the outcome diagram easier:

  1. Rename peace_resources to peace_resources_rt.
  2. Rename Item to Step decided this doesn't make sense.
  3. Create peace_resource_model to house the ResourceInteractions type, which represents:
    • From/to interactions between two resources.
    • Modification of n resources (e.g. 3 servers all have X patch applied)
    • Security group affecting n servers modified

Perhaps we do the first two as part of #187 first, then continue this.

@azriel91
Copy link
Owner Author

azriel91 commented Jul 1, 2024

Things to do:

  1. Rename Resource* to Item*.
  2. Change ItemInteraction API to clearly represent nesting vs multiple resources being interacted with -- probably create ItemInteractions.
  3. Add tests for ParamsMergeExt generated code -- structs and enums.
  4. Add channel to send ItemInteractionsExample / ItemInteractionsCurrent to WebiServer.
  5. Move Flow into flow_rt crate.
  6. Gate flow_spec_info and related types behind feature = "item_interactions".
  7. Add ItemInteractions in ItemSpecInfo (and ItemInfo?).

Changing ItemInteraction API

  1. Retain ItemLocation as is, but create one of:

    1. ItemLocationAncestors which is a Vec<ItemLocation> newtype.
    2. an ItemLocationTree which is a struct { ItemLocation, Vec<ItemLocationTree> } -- a parent ItemLocation, and any children it has. Or should it be a Map<ItemLocation, Vec<ItemLocation>>? (flat map so it's easy to see if an ItemLocation is already recorded)
  2. How about both:

    1. The ItemLocationTree is the tree of the topmost (known) ItemLocation ancestor, to all of the lowest ItemLocations.
    2. The ItemLocationAncestors is a linear list from the topmost (known) ItemLocation ancestor to each leaf ItemLocation -- one path of an ItemLocationTree.
  3. For each Item's interactions, we want to know:

    1. The source ItemLocation(s?) -- ItemLocationAncestors.
    2. The destination ItemLocation(s) -- Vec<ItemLocationAncestors>? or ItemLocationTree, where each leaf node is a destination.

    Other names considered for ItemLocationAncestors are:

    • ItemLocationAncestry
    • ItemLocationTaxonomy
    • ItemLocationLayers

    Use cases we know of:

    1. Upload a file -- one source, one dest.
    2. Download a file -- one source, one dest.
    3. Launch servers -- one source (localhost), one dest (AWS).
    4. Wait for servers to start up -- multiple within (do we need the ItemLocationTree for the cloud provider / subnet context? or leverage previous resource tracking to work it out?).
    5. Wait for endpoints to become available -- one source, multiple dest (query each endpoint).
    6. Do we want ItemInteractions to be queried multiple times while Apply is happening? -- i.e. some servers may have started up, and so we need the Item to report that to us.
    7. Notably, we want these ItemInteractions to be queriable without the items actually existing -- so we can generate diagrams to demonstrate what would happen upon execution.

@azriel91
Copy link
Owner Author

azriel91 commented Sep 20, 2024

Generating outcome diagram

  1. Params specs are defined by user.

  2. They confirm, and CmdCtx is created and set in some shared area.

  3. InfoGraph which is cloneable and serializable is generated and sent to the leptos server.

    It is immensely difficult to get CmdCtx to be stored in leptos context, and information passed to leptos Components. This is even before attempting to get CmdExecutions working.

    Therefore we do this:

    1. This should be done outside of the leptos components because of the way CmdCtx and Item are written.
    2. params_specs and resources are needed to generate the diagram, which are owned by CmdCtx.
    3. resources is behind &mut in the SingleProfileSingleFlowView, which cannot be accessed behind a ReadSignal. Also, we cannot Clone it and send to the leptos context.
    4. InfoGraph is Cloneable / Serializable, so if we do this work outside leptos, and send the InfoGraph back, it should make things compile.

Holding CmdExecutions in WebiOutput

Use cases

  1. Display selected Flow.

  2. Start execution for selected Flow

    1. Instantiate CmdCtx --> Builder is mainly invoked by tool developer.
    2. Start CmdExecution --> returns a Future<Output = ??> output differs based on CmdCtx / what is called.
    3. Update InfoGraph when progress happens.
  3. Render execution

    1. Look up execution progress and outcome InfoGraphs by ID.
    2. Update components.
  4. Pause execution

    1. Look up CmdExecution by ID.
    2. Check execution status.
    3. Send interrupt signal.
  5. Return execution result when finished.

    1. Look up execution status by ID.
  6. Run another execution.

    Either:

    1. Look up CmdCtx by ID.

    Or:

    1. Create a new CmdCtx.

Solutioning

CmdExecution Storage and Retrieval

Because these are different types (based on type parameter, return type), can we not store the exact type?

Options:

  1. Store a simple Fn() -> impl Future<Output = ()> wrapper.

  2. Don't store CmdExecution / its returned task, but send the task to tokio::task::spawn, and the task writes known simple types (e.g. Interruptibility, ExecutionStatus) (non-generic types) to the storage.

    This way, the type parameters can be confined to WebiOutput::add_flow_and_cmd_ctx_handler or similar.

We only really need to have the type parameters if they are used to adjust function signatures, not for runtime map lookups. The latter we can do via TypeId.

Adjusting function signatures is needed when we need to take in the tool developer's type, and e.g. look up a map, or downcast State / a Param type. These should largely be hidden behind a type erased trait as much as possible.

@azriel91
Copy link
Owner Author

azriel91 commented Sep 21, 2024

To Dos:

  • Flow::item_locations_and_interactions_current needs to correctly hide nodes/edges if the nodes are from item_interactions_example.
  • OutcomeInfoGraphCalculator::calculate_* needs to compute edges.
  • Add tests for ParamsSpec::resolve{_partial} InMemory with different ValueResolutionCtxs.
  • A number of incorrect <Transition> / leptos resource usages in flow_graph.rs. See browser console for errors.
  • Is the ItemLocation merging correct? What if we had A and C, A and B, and B and C ancestors. Should we merge them into A, B, C? Because someone else's B may actually represent a different concept, which just happens to have the same ItemLocation values. Source files concerned: Flow, OutcomeInfoGraphCalculator.
  • Render markdown -- see WebiServer receiving WebUiUpdate::Markdown.
  • Unit tests for Progress, and OutputWrite impls -- sending CmdBlockStart.
  • Move CmdBlockItemInteractionType / all of peace_core::progress to new peace_progress_model crate.
  • Save Generated::Values in states_goal, and not overwrite it during state_goal_try_exec. See 3a74056.
  • State maybe should be split into the State that represents contents, and the Location where it resides. Diff doesn't care about the Location between current vs goal, but it does care if the location changes for the dest param, e.g. destination path of where to store it changes. i.e. params_prev.dest() != params_next.dest() is a difference and the file needs to move, but params.dest() vs params.source() being different, with contents being the same, is not a state_diff() difference.
  • Move Flow into flow_rt crate.
  • Add tests for ParamsMergeExt generated code -- structs and enums.

@github-project-automation github-project-automation bot moved this from In Progress to Done in Peace: UI Oct 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

1 participant