Skip to content

feat(task-service)!: add spec compliant task service support#107

Merged
jayzhudev merged 8 commits into
NVIDIA:mainfrom
jayzhudev:feat/task-service
May 25, 2026
Merged

feat(task-service)!: add spec compliant task service support#107
jayzhudev merged 8 commits into
NVIDIA:mainfrom
jayzhudev:feat/task-service

Conversation

@jayzhudev
Copy link
Copy Markdown
Contributor

@jayzhudev jayzhudev commented May 23, 2026

Adding this support for RMS firmware upload status checks.

Breaking change:

  • When the task-service feature is enabled, the redfish::Error now has 2 new variants.

@jayzhudev jayzhudev requested a review from yoks May 23, 2026 04:28
@jayzhudev jayzhudev marked this pull request as draft May 23, 2026 04:40
Adding this support for RMS firmware upload status checks.

Signed-off-by: Jay Zhu <jayzhu@nvidia.com>
@jayzhudev jayzhudev force-pushed the feat/task-service branch from dbf067b to 8843eb4 Compare May 23, 2026 05:37
@jayzhudev jayzhudev marked this pull request as ready for review May 23, 2026 05:37
@jayzhudev jayzhudev marked this pull request as draft May 23, 2026 05:40
@jayzhudev jayzhudev force-pushed the feat/task-service branch from 7d49e50 to 815cfe1 Compare May 23, 2026 05:47
@jayzhudev jayzhudev marked this pull request as ready for review May 23, 2026 05:57
@jayzhudev jayzhudev requested a review from poroh May 23, 2026 06:12
Comment thread redfish/src/task_service/mod.rs Outdated
/// # Errors
///
/// Returns error if retrieving task data fails.
pub async fn task(&self, task_path: impl ToString) -> Result<Arc<Task>, Error<B>> {
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.

If I understand correctly then it is from Location header from the result of the operation. It would be nice to:

  1. Introduce type for a Location header value
  2. Use it here and task service should check that Location header value corresponds to its own odata.id.

This will express additional knowledge trough type system and better errors if somebody by mistake will use task service for non-task values (I think some vendors may have their own async job services, see Dell OEM jobs for example).

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.

Maybe we also should add separate function that can check that Location is valid Task resource.

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 very good and thoughtful call, thanks!

After some thinking, I see two options here:

  1. add a Location type. The intent is clearer to the caller but it wouldn't prevent caller mistakes of calling a wrong task service instance - we would still need validation in task calling.

  2. keep the API simple and only add validation inside TaskService::task(). The caller passes the task path, and TaskService checks it is under the BMC's Tasks collection before polling.

Option 2 seems to have the right tradeoff to me because the validation is task-specific, and TaskService already has the Tasks collection needed to do it.

@jayzhudev jayzhudev requested a review from poroh May 23, 2026 21:14
Signed-off-by: Jay Zhu <jayzhu@nvidia.com>
@jayzhudev jayzhudev changed the title feat(task-service): add spec compliant task service support feat(task-service)!: add spec compliant task service support May 23, 2026
Comment thread redfish/src/task_service/mod.rs Outdated
/// ```
pub struct TaskService<B: Bmc> {
data: Arc<TaskServiceSchema>,
task_collection: TaskCollectionPath,
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.

Think we should not keep this information inside TaskService. All information is in data (odata.id). Just add method to ODataId type that can check that one OdataId is_path_prefix for another. No need to trim_end_matheces etc. Just add one method here and use it is needed.

impl ODataId {

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.

Agreed, I've updated the implementation.

Comment thread redfish/src/task_service/mod.rs Outdated
use crate::schema::task_service::TaskService as TaskServiceSchema;

#[doc(inline)]
pub use crate::schema::task::Task;
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.

nv-redfish has two concept:

  1. Full wrapper like Chassis where you have different custom methods
  2. Link that internally contains just odata-id reference for the object.

It seems that Task should be a link here:

Suggested change
pub use crate::schema::task::Task;
use crate::entity_link::EntityLink;
use crate::schema::task::Task as TaskSchema;
/// Link for accessing task.
pub type TaskLink<B> = EntityLink<B, TaskSchema>;

Comment thread redfish/src/task_service/mod.rs Outdated
///
/// Returns error if the service does not expose a Tasks collection, if the
/// path is outside that collection, or if retrieving task data fails.
pub async fn task(&self, task_path: impl AsRef<str>) -> Result<Arc<Task>, Error<B>> {
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.

use crate::core::AsyncTask;
Suggested change
pub async fn task(&self, task_path: impl AsRef<str>) -> Result<Arc<Task>, Error<B>> {
pub fn task_link(&self, async_task: AsyncTask) -> Result<TaskLink, Error<B>> {

Internally task_link should check that task service odata id is parent path for AsyncTask::id and constructs link only if this is true.

Note that this method doesn't retrieve any data, just creates handle that can be used to retrieve data. See:

pub async fn fetch(&self) -> Result<Arc<T>, Error<B>> {

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.

Thanks for sharing this! This utility seems to be the right pattern to use. I've updated the implementation.

…taId

Add ODataId prefix checks and use them to validate async task links
without caching path prefixes.

Signed-off-by: Jay Zhu <jayzhu@nvidia.com>
@jayzhudev jayzhudev requested a review from poroh May 25, 2026 18:20
Comment thread redfish/src/task_service/mod.rs Outdated
pub struct TaskService<B: Bmc> {
data: Arc<TaskServiceSchema>,
task_collection: TaskCollectionPath,
task_collection: ODataId,
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.

This copy of odata_id is redundant. You can use data.odata_id() when this value is needed.

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.

Replaced it with data.tasks.odata_id.

Comment thread redfish/src/task_service/mod.rs Outdated
if !task_path.starts_with(self.task_collection.prefix.as_str()) {
/// Returns error if the task ID is not a child of this service's Tasks
/// collection.
pub fn task_link(&self, task: &AsyncTask) -> Result<TaskLink<B>, Error<B>> {
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.

To avoid "clones" just use task: AsyncTask.

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.

The tradeoff is around consuming the task versus cloning just the id (current implementation). I chose the latter in case the caller still needs the task (for the retry_after_secs field).

Signed-off-by: Jay Zhu <jayzhu@nvidia.com>
@jayzhudev jayzhudev requested a review from poroh May 25, 2026 18:34
jayzhudev added 2 commits May 25, 2026 12:53
If a caller needs other fields in the AsyncTask, it can choose to clone
other fields or the entire AsyncTask before it's consumed by task_link.

The idea is that task_link doesn't implicitly clone the ID string within
the method - cloning happens based on the choice of the caller.

Signed-off-by: Jay Zhu <jayzhu@nvidia.com>
Rename async task IDs to task locations, convert retry_after_secs to std::time::Duration,
align TaskService errors, docs, examples, and tests with the new naming.

Signed-off-by: Jay Zhu <jayzhu@nvidia.com>
@jayzhudev jayzhudev force-pushed the feat/task-service branch from 8784288 to 79d1c27 Compare May 25, 2026 20:18
@jayzhudev jayzhudev merged commit 8bd4ebd into NVIDIA:main May 25, 2026
4 checks passed
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