Skip to content

Commit

Permalink
Merge pull request #5176 from voxel51/legacy-orcs
Browse files Browse the repository at this point in the history
Allow legacy orchestration
  • Loading branch information
brimoor authored Nov 22, 2024
2 parents 488cb28 + 2ede748 commit 7b079dc
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 171 deletions.
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}
/>
}
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

0 comments on commit 7b079dc

Please sign in to comment.