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

Allow legacy orchestration #5176

Merged
merged 6 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions app/packages/operators/src/SplitButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ListItemText,
Tooltip,
ButtonProps,
Box,
} from "@mui/material";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
import { onEnter } from "./utils";
Expand Down Expand Up @@ -128,6 +129,9 @@ export default function SplitButton({
key={option.id}
disabled={option.disabled}
selected={option.selected}
sx={{
cursor: option.onClick ? "pointer" : "default",
}}
onClick={() => handleSelect(option)}
>
<ListItemText
Expand All @@ -141,9 +145,19 @@ export default function SplitButton({
<PrimaryWithTag
label={option.choiceLabel || option.label}
tag={option.tag}
disabled={option.disabled || !option.onClick}
brimoor marked this conversation as resolved.
Show resolved Hide resolved
/>
}
secondary={option.description}
secondary={
<Box
sx={{
fontSize: "11px",
"& *": { fontSize: "inherit" },
}}
>
{option.description}
</Box>
}
/>
</MenuItem>
))}
Expand All @@ -158,13 +172,13 @@ export default function SplitButton({
);
}

function PrimaryWithTag({ label, tag }) {
function PrimaryWithTag({ label, tag, disabled }) {
const theme = useTheme();
const tagEl = tag ? (
<span
style={{
fontSize: "11px",
color: theme.custom.primarySoft,
color: disabled ? theme.text.secondary : theme.custom.primarySoft,
marginLeft: "5px",
}}
>
Expand Down
45 changes: 36 additions & 9 deletions app/packages/operators/src/state.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { useAnalyticsInfo } from "@fiftyone/analytics";
import * as fos from "@fiftyone/state";
import { debounce } from "lodash";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import {
atom,
selector,
Expand Down Expand Up @@ -32,6 +38,7 @@ import {
import { OperatorPromptType, Places } from "./types";
import { OperatorExecutorOptions } from "./types-internal";
import { ValidationContext } from "./validation";
import { Markdown } from "@fiftyone/components";

export const promptingOperatorState = atom({
key: "promptingOperator",
Expand Down Expand Up @@ -231,8 +238,8 @@ function useExecutionOptions(operatorURI, ctx, isRemote) {
export type OperatorExecutionOption = {
label: string;
id: string;
description: string;
onClick: () => void;
description: string | React.ReactNode;
onClick?: () => void;
isDelegated: boolean;
choiceLabel?: string;
tag?: string;
Expand All @@ -251,7 +258,7 @@ const useOperatorPromptSubmitOptions = (
const persistUnderKey = `operator-prompt-${operatorURI}`;
const availableOrchestrators =
execDetails.executionOptions?.availableOrchestrators || [];
const hasAvailableOrchestators = availableOrchestrators.length > 0;
const hasAvailableOrchestrators = availableOrchestrators.length > 0;
const executionOptions = execDetails.executionOptions || {};
const defaultToExecute = executionOptions.allowDelegatedExecution
? !executionOptions.defaultChoiceToDelegated
Expand Down Expand Up @@ -287,7 +294,7 @@ const useOperatorPromptSubmitOptions = (
label: "Schedule",
id: "schedule",
default: defaultToSchedule,
description: "Run this operation on your compute cluster",
description: "Run this operation in the background",
onSelect() {
setSelectedID("schedule");
},
Expand All @@ -300,7 +307,7 @@ const useOperatorPromptSubmitOptions = (

if (
executionOptions.allowDelegatedExecution &&
hasAvailableOrchestators &&
hasAvailableOrchestrators &&
executionOptions.orchestratorRegistrationEnabled
) {
for (let orc of execDetails.executionOptions.availableOrchestrators) {
Expand All @@ -321,6 +328,25 @@ const useOperatorPromptSubmitOptions = (
isDelegated: true,
});
}
} else if (
executionOptions.allowDelegatedExecution &&
executionOptions.allowImmediateExecution &&
executionOptions.orchestratorRegistrationEnabled &&
!hasAvailableOrchestrators
) {
const markdownDesc = React.createElement(
Markdown,
null,
"[Learn how](https://docs.voxel51.com/plugins/using_plugins.html#delegated-operations) to run this operation in the background"
);
options.push({
label: "Schedule",
choiceLabel: `Schedule`,
tag: "NOT AVAILABLE",
id: "disabled-schedule",
description: markdownDesc,
isDelegated: true,
});
}

// sort options so that the default is always the first in the list
Expand Down Expand Up @@ -366,10 +392,11 @@ const useOperatorPromptSubmitOptions = (
if (selectedOption) selectedOption.selected = true;
const showWarning =
executionOptions.orchestratorRegistrationEnabled &&
!hasAvailableOrchestators &&
!hasAvailableOrchestrators &&
!executionOptions.allowImmediateExecution;
const warningMessage =
"There are no available orchestrators to schedule this operation. Please contact your administrator to add an orchestrator.";
const warningStr =
"This operation requires [delegated execution](https://docs.voxel51.com/plugins/using_plugins.html#delegated-operations)";
const warningMessage = React.createElement(Markdown, null, warningStr);

return {
showWarning,
Expand Down
Binary file not shown.
45 changes: 2 additions & 43 deletions docs/source/plugins/developing_plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -992,9 +992,8 @@ contains the following properties:
instance that you can use to read and write the :ref:`state <panel-state>`
and :ref:`data <panel-data>` of the current panel, if the operator was
invoked from a panel
- `ctx.delegated` - whether delegated execution has been forced for the
operation
- `ctx.requesting_delegated_execution` - whether delegated execution has been
- `ctx.delegated` - whether the operation was delegated
- `ctx.requesting_delegated_execution` - whether delegated execution was
requested for the operation
- `ctx.delegation_target` - the orchestrator to which the operation should be
delegated, if applicable
Expand Down Expand Up @@ -1248,46 +1247,6 @@ of the current view:
to specify the available execution options as described in the previous
section.

Alternatively, you could simply ask the user to decide:

.. code-block:: python
:linenos:
def resolve_input(self, ctx):
delegate = ctx.params.get("delegate", None)
if delegate:
description = "Uncheck this box to execute the operation immediately"
else:
description = "Check this box to delegate execution of this task"
inputs.bool(
"delegate",
label="Delegate execution?",
description=description,
view=types.CheckboxView(),
)
if delegate:
inputs.view(
"notice",
types.Notice(
label=(
"You've chosen delegated execution. Note that you must "
"have a delegated operation service running in order for "
"this task to be processed. See "
"https://docs.voxel51.com/plugins/index.html#operators "
"for more information"
)
),
)
def resolve_delegation(self, ctx):
return ctx.params.get("delegate", None)
.. image:: /images/plugins/operators/operator-user-delegation.png
:align: center

.. _operator-reporting-progress:

Reporting progress
Expand Down
8 changes: 8 additions & 0 deletions docs/source/plugins/using_plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,14 @@ FiftyOne Open Source users can run delegated operations via the
This command starts a service that will continuously check for any queued
delegated operations and execute them serially in its process.

You must also ensure that the
:ref:`allow_legacy_orchestrators <configuring-fiftyone>` config flag is set
in the environment where you run the App, e.g. by setting:

.. code-block:: shell
export FIFTYONE_ALLOW_LEGACY_ORCHESTRATORS=true
.. _delegated-orchestrator-teamas:

FiftyOne Teams
Expand Down
Loading
Loading