Skip to content

Add support for table commands with return data - and DownloadSourceCodeCommand. - #439

Open
Jayson Maxson (jmaxson-ms) wants to merge 15 commits into
mainfrom
user/jmaxson/newTableCommands
Open

Add support for table commands with return data - and DownloadSourceCodeCommand.#439
Jayson Maxson (jmaxson-ms) wants to merge 15 commits into
mainfrom
user/jmaxson/newTableCommands

Conversation

@jmaxson-ms

@jmaxson-ms Jayson Maxson (jmaxson-ms) commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

This branch introduces a new generation of table commands (TableCommand3) that supports async execution, strongly-typed contexts and results, and column-scoped commands. It also adds the first concrete TableCommand3: DownloadSourceCode. Existing ITableCommand / ITableCommand2 continue to work via adapter types now hosted in the SDK.

@jmaxson-ms
Jayson Maxson (jmaxson-ms) force-pushed the user/jmaxson/newTableCommands branch from 6d3b196 to 7b68d36 Compare August 7, 2026 17:18
@jmaxson-ms
Jayson Maxson (jmaxson-ms) marked this pull request as ready for review August 7, 2026 17:35
@jmaxson-ms Jayson Maxson (jmaxson-ms) changed the title User/jmaxson/new table commands Add support for table commands with return data - and DownloadSourceCodeCommand. Aug 7, 2026
Comment thread src/Microsoft.Performance.Toolkit.Engine/RuntimeExecutionResults.cs
/// recognize (and can execute) it. Unknown command types may be safely
/// ignored.
/// </summary>
public abstract class TableCommand3

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just change this to an interface. Easier to mock when testing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another benefit of making it an interface is you can make implement it directly in the legacy classes like TableCommand2. No need for the standalone adapters

@jmaxson-ms Jayson Maxson (jmaxson-ms) Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jing, I think we should talk offline about this proposed change. I'm not sure that, when thinking about what the proposed change would entail, it would work as smoothly as it seems at an abstract level. (wrt to the second part of your comment specifically)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're making this an interface but leaving the adapters.

/// <see cref="VoidTableCommandResult"/> for commands that do not
/// produce a meaningful result.
/// </remarks>
public interface ITableCommand3Result;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? If we don't have any constraint on it, why not just allow all types?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is leftover from a legacy implementation. Thanks for pointing it out.

}

/// <inheritdoc />
public override Type ContextType => typeof(TContext);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this used?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

forgot to remove these. thanks

/// <see cref="VoidTableCommandResult"/> when the command does not
/// produce a value.
/// </typeparam>
public abstract class TableCommand3<TContext, TResult>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be an interface too

/// A command with the same <see cref="TableCommand3.CommandName"/>
/// has already been added to this instance (case-insensitive).
/// </exception>
ITableBuilder AddTableCommand3(TableCommand3 command);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding a general TableCommand3, we should restrict it to only the table commands we support i.e.

ITableBuilder AddDownloadSourceCodeCommand(DownloadSourceCodeCommand command);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I prefer the more general approach.

  • we don't need to ever worry about a huge number of methods
  • this allows for a host and a plugin to have the ability to add extra functionality that doesn't exist in the SDK

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our primary use case is for WPA though. I don't think we should allow people to add commands that WPA doesn't support. That's just misleading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO if someone wants to develop a different host than WPA, they should fork this repo. This repo needs to first make sure things work with WPA before worrying about other hosts

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a different philosophy than we had when creating this SDK. Happy to chat offline about it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've decided to go ahead and make these specific command methods.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this does not tie the host to WPA, but it does restrict commands to those supported by the SDK.

/// <summary>
/// Gets the identifier of the column that this command targets.
/// </summary>
Guid ColumnId { get; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel this should be an interface method bool IsColumnSupported(IDataColumn) method for ITableCommand3

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's chat offline

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chatting offline, we decided on bool IsColumnSupported(Guid)

@jmaxson-ms Jayson Maxson (jmaxson-ms) Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this ties table commands to one or more columns, but we believe this has been and will continue to be the case. If the need arises, we could re-evaluate in future changes.

/// runtime type of each command to determine whether they recognize
/// it. Unknown command types may be safely ignored.
/// </summary>
public IReadOnlyList<TableCommand3> Commands { get; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to define an extension method that makes it easier for WPA to know what it needs to handle:

static void Visit(this ITableCommand3 command,
  Action<TableCommand2> visitCommand2,
  Action<DownloadSourceCodeCommand> visitDownloadSourceCommand,
  ...) // more in the future

/// A command with the same <see cref="TableCommand3.CommandName"/>
/// has already been added to this instance (case-insensitive).
/// </exception>
ITableBuilder AddTableCommand3(TableCommand3 command);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't work to return ITableBuilder here if we want ITableBuidlerWithRowCount to also use this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants